nuckolhead
nuckolhead

Reputation: 101

NodeJS cookies don't work with sessions in Express 4

I've updated my NodeJS application to Express 4.0 and now I can't set my own cookies in addition to the express-session cookie. This problem only happens on the first request of any session, when the user reloads the page the custom cookies are there.

var express = require('express');
var routes = require('./routes');
var http = require('http');
var path = require('path');
var session = require('express-session');

var app = express();

app.set('port', process.env.PORT || 3000);

app.use(express.static(path.join(__dirname, 'public')));
app.use(require('body-parser')());
app.use(require('method-override')());
app.use(require('cookie-parser')('cookie-secret'));
//app.use(session({ secret: 'secret', key: 'sid'})); //uncomment this to see the problem

app.get('/', function(req, res, next) {
    res.cookie('testing', 'test'); //this isn't set if using 'app.use(session...)'
    res.send('This is a cookie test');
});

http.createServer(app).listen(app.get('port'), function(){
    console.log('Express server listening on port ' + app.get('port'));
});

To test: 1. Run the above code, the cookie "testing" is sent to the browser correct. 2. Then clear the cookies and uncomment the "app.use(session..." line. 3. Run the application and the only cookie is the "sid". Where's "testing"? 4. Reload the page (without clearing cookies) and the "testing" cookie is there.

It's essential that all of my cookies are there on the first request.

Upvotes: 6

Views: 3641

Answers (3)

Brandon Clark
Brandon Clark

Reputation: 796

In express-session you are attempting to use the key: option which was replaced with name: option. You will want to use the genid: option to set the sid, make sure it is unique(I suggest, uuid version 4). The express-session package will also handle your cookie management.

// Session create
var hour = 3600000;

app.use(session({
    genid: function(req) {
          return uuid.v4(); // This comes from the node-uuid package
    },
    secret: 'secret key',
    cookie: { secure:  true,
              expires: new Date(Date.now() + hour),
              maxAge:  hour },
    saveUninitialized: true,
    resave: true
}));

To access the session data:

req.session

To access the cookie data:

req.session.cookie

Upvotes: 2

malix
malix

Reputation: 3582

This works for me:

var mw = {
  favicon: require('static-favicon'),
  logger: require('morgan'),
  bodyParser: require('body-parser'),
  cookieParser: require('cookie-parser'),
  session: require('express-session'),
  methodOverride: require('method-override')
};

var MongoStore = require('connect-mongo')(mw);
app.store = new MongoStore(...);


app.use(function(req, res, next) {
  if ('HEAD' === req.method || 'OPTIONS' === req.method) return next();
  var writeHead = res.writeHead;
  res.writeHead = function() {
    res.cookie('XSRF-TOKEN', req.session && req.session._csrfSecret);
    writeHead.apply(res, arguments);
  };
  next();
});

app.use(mw.session({
  key: 'yourCookieID',
  cookie: {
    maxAge: 3600000 * 24 * 7
  },
  store: app.store
}));

Upvotes: 3

mscdex
mscdex

Reputation: 106736

This is a known problem. See this GH issue.

Upvotes: 1

Related Questions