Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Shared Sessions between Node Apps?

I currently have two separate node apps running on two different ports but share the same backend data store. I need to share users sessions between the two apps so that when a user logs into through one app, their session is available and they appear to logged into the other app. In this case, its' a public facing website and an administrative backend.

Our setup is the following:

  • node with express
  • passport is being used to handle auth with Local Strategy
  • we're using connect-redis to allow us to share sessions via redis.
  • our domains look like this: www.mydomain.com and adm.mydomain.com

The config for for session stuff (and redis) is the same for both apps:

session: {
    options: {
        secret: "my secret",
        cookie: {
            domain: "mydomain.com",
            maxAge:1000*60*60*24
        }
    },
    redis: {
        host: 'my host',
        maxAge: 86400000,
        secret: "my secret"
    }
}

The config for session stuff in app.js looks like this:

if ( app.settings.env === "production" ) {
    session.options.store = new RedisStore(session.redis);
}
app.use(express.session(session.options));
app.use(passport.initialize());
app.use(passport.session({ secret: 'a different secret' }));

What I expect it to do: Allow us to see the same session id in the cookie between the two apps.

So my question is: How do I set up express, redis and passport so that you can have sessions shared across different subdomains?

like image 944
jpittman Avatar asked Nov 29 '12 01:11

jpittman


2 Answers

Maybe a bit outdated, but at this time, Express-session can recognise domain option for cookie. According to source:

function session(options){
  var options = options || {}
  //  name - previously "options.key"
    , name = options.name || options.key || 'connect.sid'
    , store = options.store || new MemoryStore
    , cookie = options.cookie || {}
      ...

And this is for setting cookie:

var Cookie = module.exports = function Cookie(options) {
  this.path = '/';
  this.maxAge = null;
  this.httpOnly = true;
  if (options) merge(this, options);
  ...

So, something like this will work for current 1.10.1 master:

secret: "my secret",
    cookie: {
        domain: "mydomain.com",
like image 59
f1nn Avatar answered Nov 02 '22 17:11

f1nn


Express-session does not seem to recognize the "domain" option for cookies hence your problem. The cookie storing the session id is automatically tied to the domain for each app and so it cannot be shared.

One option is to write your own single-sign-on module to share sessions across webapps. It would probably live in an app.use() declaration fairly early in the execution order and would simply create a separate cookie (which would be cross-domain), create a separate SSO session id, and store the SSO id in this new cookie. Afterwards, you simply cross-populate req.session and req.sso-session as needed.

like image 39
takinola Avatar answered Nov 02 '22 18:11

takinola