Org has 2 customer portals/sites e.g.


Most users have access to both portals, users have same set of credentials for both of the portals.

If user logins into one portal(say xxxx) & clicks on URL of another portals(url of yyyy), he is directed to login page of the 2nd portal(login page of yyyy).

I believe, as both sites are on same domain, have same set of credentials; need of having to enter same credentials once again can be avoided.

How can we ensure that - Login into one force.com site, logins user in 2nd site as well?


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.

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:

Step 0: 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)

Step 1: 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 Username__c, Password__c, Security-Questions, 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 RecordTypes for Portal__c.

RecordType = Portal: Houses Site parameters. e.g.

  • Session Cookie Name
  • 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-RecordType is.)
  • The name of the lookup-field in the Portal__c:User (i.e. the Portal__c record with the "User" RecordType) [more about the User RecordType in a sec]
  • I have a set of string fields called Login_Page__c, Home_Page__c, Register_Page__c, Error_Page__c, Expiration_Page__c, 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 Account or 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 RecordTypes.

The Portal__c:User records have:

  • Username
  • 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.

Step 2: 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 ApexPages.StandardControllers:

  • 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 User-record and id just like a StandardController would.
  • 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.

  • We have achieved that by actually opening one portal in another in hidden iframe. This way we manage to receive cookies of both portals in browser. – Ganesh Bhosle Oct 9 '13 at 12:45
  • I would like to know our way of doing this. Code may be unnecessary but you can explain this in bit more detail. – Ganesh Bhosle Oct 9 '13 at 12:47
  • I added an update :) – Scott Pelak Oct 9 '13 at 17:24

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.