I've created my own login objects, classes, and pages where I keep track of users, and when they log on, I create my own
SessionId and store the info in an
object + a client side
Cookie. Then, I have a method (used in the
Action parameter of
apex:page) that validates my session for every
Portal Site page visited.
I too have multiple sites for a single org with users existing among all of my
portals. I differentiate
Portal sessions by the unique
cookie name for that particular Portal (+ the
record where the Session info is stored).
If you'd like to know more about my setup (including some
code), let me know, and I can post some details.
We manage multiple orgs, and each org may contain a number of Sites. Additionally, each site generally uses different
sObjects as "User records" (e.g. the associated user record is an
Account record or
Employee__c record). So, after creating a handful of Sites (custom portals for different client needs), each with their own login page & home page & ..., I began to see how to generealize this process.
It's split into a few steps:
For security, when a user logs in, a
SessionID is created (a long randomly generated string) and is stored in a Cookie (along with the User's username). Then, whenever the user navigates to any of the other site pages, I first call a method in the
action attribute of
apex:page that verifies the
SessionID (along with checking the
SessionID isn't "too old").
I had to create code to do this function (obviously), and I realized this process could be generalized. (more to come about this below)
Since each "User record" may belong to a different sObject, and I want to use this code across many orgs (not necessarily sharing the same custom sObjects), I needed to dissociate the "User records" from the
SessionID data. So, I created a custom object called
Portal__c to house User-information and Session-data as well as Site-specific data accomplished by creating a number of
RecordType = Portal: Houses Site parameters. e.g.
- Which Site the record belongs to
- How long the allowable Session Length should be (before requiring the user to re-login.)
- Which sObject designates the "User Record" (along with noting what the User-
- The name of the
lookup-field in the
Portal__c:User (i.e. the
Portal__c record with the "
RecordType) [more about the
User RecordType in a sec]
- I have a set of string fields called
Forgot_Page__c where I can set the name of the corresponding VF Page. (This allows for easy navigation.)
RecordType = User:
Since each User record could be attached to different sObjects (like
Employee__c), we will need a lookup to each of these different sObjects. To make administration easier, I create a different "User"-
RecordType for each Site. (Tt is sufficient to have a different
RecordType per distinct User-record-sObject.) This is why I allow the
Portal__c:User records to have different
Portal__c:User records have:
- Password (encrypted)
- lookup to the associated "User Record"
- picklist of Security Questions
- Security Answer (encrypted)
RecordType = Session:
Houses Session Data and has a lookup to the associated Portal__c:User record. Every time a user logs in, a new
Portal__c:Session record is created.
There's not much here:
- SessionID (encrypted)
- lookup to Portal__c:User record
- Long Text Area field to house the Session History (an attempt to reduce the # of records created since the cost of each record is independent to how much data is stored within it). I have code that writes the Session History to this field whenever a User navigates through the Site.
I created an Apex class called
Portal to manage all this Portal and User information in a really easy-to-use way. In fact, it mimics some of the functionality of
- I wrote a lot of back end code to manage creating and verifying the Portal Sessions.
- Whenever a user navigates to a Site page, a new
Portal instance is created, and it collects all the relevant data.
- The instance gives you the associated
id just like a
- It's very easy to verify the SessionID, and if it is invalid, it redirects to the LOGIN page automatically.
- There are tools to navigate to different pages.
Portal portal = new Portal('mySiteName');
pageReference goHome = portal.getPage(Portal.Page.HOME);
id myRecordId = portal.getUserId();
pageReference verifySessionResult = portal.getSessionCheck();
pageReference theLoginPage = portal.loginPage(); // an easy escape to the login page
That's essentially it. It's really cool because it's a breeze to create new portal! The only real-work is creating the VF pages.
I'm still tweaking everything, and there is definitely room for improvement.