4

Passport is great. I now discovered that I have some problem with how it handles sessions. I must be using it wrong.

All works well for me with login + sessions + user data I store in my database. However I find that when I move to production environment (cloud on EC2 with multiple servers), I lose the login session each time. This is now clear to me - probably happens since the session is unique to each server.

So my question is - how do I get around this.. I guess I will need to store my own cookie on the user's browser?

Does this mean that I cannot use express.session at all?

Thanks, Ilan

Ilan lewin
  • 1,599
  • 1
  • 14
  • 24

2 Answers2

8

OK, So basically what I was looking for (not sure it would be the same answer for everyone else) was a way to store session data between loadbalanced instances without making a DB call for every page view, which seems excessive to me, since I just need to keep the user signed in to Google/FB.

It seems that the answer I was looking for was the cookie-session middleware https://github.com/expressjs/cookie-session

This needs to replace the default express.session mechanism which uses MemoryStore. BTW MemoryStore itself gives you a warning when run that it will not scale past a single process, and also that it may cause a memory leak.

Which if I understand correctly is serializing the session data itself into the session cookie (encrypted) instead of just using a session ID in the session cookie. This seems perfect to me. Obviously I don't expect it to work if you have a lot of session data, since a cookie is limited in size. In my case, I just needed the name, ID and avatar url, so I think this will suffice. Thanks for everyone who helped.

Ilan lewin
  • 1,599
  • 1
  • 14
  • 24
  • Since v1.5.0 of **express-session**, the cookie-parser middleware no longer needs to be used for this module to work. This module now directly reads and writes cookies on req/res. Using cookie-parser may result in issues if the secret is not the same between this module and cookie-parser. – aSmater.Me May 15 '18 at 10:02
1

You need to store your session data in a 'global' area, that is accessible to all your servers. This could be redis or another DB.

Take the example from MEAN.JS. Here they use express-session with a MongoDB storage container (since they are a MEAN stack ; ), via connect-mongo. Their project is super easy to set up, if just for an example.

Code while setting up express is like this:

//top of file
var session = require( 'express-session' )
    mongoStore = require( 'connect-mongo' )( {
        session: session
    } );

//...later in setup

// Express MongoDB session storage
app.use( session( {
    saveUninitialized: true,
    resave: true,
    secret: config.sessionSecret,
    store: new mongoStore( {
        db: db.connection.db,
        collection: config.sessionCollection
    } )
} ) );

// use passport session
app.use( passport.initialize() );
app.use( passport.session() );
clay
  • 5,917
  • 2
  • 23
  • 21
  • I do have a database on my backend (dynamodb), but does that mean that there is a DB call every single page view? It seems a little excessive to me. I remember I read somewhere (actually at first that's how I though passport session worked) that you can actually seralize, encrypt and save the whole session data into a cookie, and by that nullify the need for backend storage for login data. – Ilan lewin Sep 25 '14 at 20:09
  • There are many ways to handle something like this. Be aware that anything you store solely on the client is more exposed than server-side. Yes, this is a DB call for every action that requires session authentication. Using an "in-memory" database like Redis or Memcache (available on AWS for a price) would be even faster in most cases than Dynamo or Mongo. To share sessions between servers, you need that data accessible somewhere; the example I gave is just one that was readily accessible for you. – clay Sep 26 '14 at 13:30