Set individual maxAge for sessions when using cookieSession() in connect/express

I am trying to use connect/express cookieSession() in order to store my node.js sessions in cookies (and thus, avoiding a server-side session store). This would help me to 'remember' the user when they log in and keep sessions alive even after server restarts.

I would like to do this with cookieSession():

app.use( express.cookieSession( { secret: 'secret_key' } ) );
app.use( function (req, res, next) {
    if ( req.method == 'POST' && req.url == '/login' ) {
      if ( req.body.remember ) {
        req.session.cookie.maxAge = 30*24*60*60*1000; // Rememeber 'me' for 30 days
      } else {
        req.session.cookie.expires = false;
      }
    }
    next();
});

However, this does not work, because req.session.cookie is undefined. I also tried the following, but it didn't seem to work:

app.use( express.session( { secret: 'secret_key' } ) );
app.use( function (req, res, next) {
    if ( req.method == 'POST' && req.url == '/login' ) {
      if ( req.body.remember ) {
        req.cookies['connect.sess'].maxAge = 30*24*60*60*1000; // Rememeber 'me' for 30 days
      } else {
        rreq.cookies['connect.sess'].expires = false;
      }
    }
    next();
});

I think this does what you want:

// Using express.session instead of express.cookieSession
app.use(express.session({ secret : 'secret_key' }));

app.use( function (req, res, next) {
  if ( req.method === 'POST' && req.url === '/login' ) {
    if ( req.body.remember )
    {
      req.session.cookie.maxAge = 30*24*60*60*1000;
      // needed to make the session `dirty` so the session middleware re-sets the cookie
      req.session.random = Math.random();
    }
    else
    {
      req.session.cookie.expires = false;
    }
  }
  next();
});

cookieSession does some funky stuff, like del req.session.cookie (not sure why).

Starting out with

app.use(express.cookieSession({ secret: config.server.cookieSecret }));

And changing it to

app.use(function(req, res, next) {
  express.cookieSession({
    secret: config.server.cookieSecret,
    cookie: {
      maxAge: req.param('remember') ? 20000 : 3000
    },
  })(req, res, next);
})

So, we create our own middleware, wrapped around the cookieSession middleware, changing the maxAge based on a param.

So, whenever you change the session you'll need to pass a remember in the body, query, or params( that's where req.param() looks ). In most cases, you only set a user_id to the session once, at login.

It's 3 seconds or 20 seconds to test and ensure it works.

And again, it might be not very helpful if you're setting stuff to your session a lot, but if you just set a user_id to session at login, this is all you need.

If you are setting lots of stuff to your session, you should know that data get passed around at every request, and you should save only the minimum to the session, like user_id, then look up the data you need for each request, to keep the overhead down on the user.

You have to first set req.session.cookie so that you can set maxAge. Trying to use it before you set it gives req.session.cookie is undefined

express.cookieSession has default values which it accepts, see here. You should mention all the parameters you are going to use. You can set cookie via the following :

app.use(express.cookieSession({ secret: 'secret_key', cookie :{ path: '/', httpOnly: true, maxAge: 30*24*60*60*1000} });

A little late to the table but I thought this answer may help people going forward...

I was using cookie-session which doesn't create a cookie object on request.session. To properly implement rememberMe functionality using request.session.cookie I switched cookie-session to express-session and that solved everything. So now there is a cookie object on session and doing this inside of a request is possible...

npm install express-session

app.post('/login', function(request, response, next) {
    passport.authenticate('local', function(err, user, info) {
        if(err) return next(err);
        if(!user) {
            request.flash('loginMessage', info.message);
            return response.redirect('/account/login');
        }

        request.login(user, function(err) {
            if(err) return next(err);

            if(request.body.rememberMe)
                request.session.cookie.maxAge = 2592000000;
            else
                request.session.cookie.expires = false;

            return response.redirect(options.redirect);
        });
    })(request, response, next);
});

This is also pretty late but it might help other people.

It seems like to me the best way to persist your session data is to store it in something like redis. The question asked for a way that didn't use server storage, but I think he was referring more to MemoryStore. Maybe not but either way this is what I did.

I used express-session and connect-redis

npm install -g connect-redis
npm install -g express-session

Then you configure stuff.

// session modules
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var session = require('express-session')
var redisStore = require('connect-redis')(session); // this sets up Redis to work with your session cookies
var app = express();

Then you just initiate your session with the store option set to your redisStore. The maxAge part sets the lifetime of each session to an hour, the session middleware resets it when it's accessed.

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(session({ 
    store: new RedisStore({
        host:'127.0.0.1',
        port:6380,
        prefix:'sess'
    }),
    cookie: {maxAge: 3600000 },
    secret: 'session_secret' 
}));

Now when a client connects, express should store the session data automatically in a Redis data structure. Since it's not just cached in memory, your server can crash and still have all the relevant session data still available at the IP address and and port specified.

Yummy seems to allow modifying cookies expiry after creation.