Express Session Does Not Save After Redirect

11,137

There is a conflict between the livereload and the express-session in the Express 4. You can read more about it here https://github.com/expressjs/cookie-session/issues/14

But in short, the livereload must be called AFTER the session. As this:

var express     = require("express");
var http        = require("http");
var session     = require("express-session");
var livereload  = require("connect-livereload");

var app = express();
app.set("port", 9090);

/**
 * First you must config the session
 */
app.use(session({
    secret: "keyboardcat",
    name: "mycookie",
    resave: true,
    saveUninitialized: true,
    cookie: { 
        secure: false,
        maxAge: 6000000
    }
}));
/**
 * Then you can config the livereload
 */
app.use(livereload())

/**
 * This simple url should create the cookie. 
 * If you call the livereload first, the cookie is not created.
 */
app.get("/",function(req,res){
    req.session.name = "blaine";
    res.end("ok");
});

/**
 * If you call the livereload first, the session will always return nothing
 * because there is no cookie in the client
 */
app.get("/me",function(req,res){
    var name = req.session.name;
    var message = "Hello [" + name + "]!";
    res.end(message);
});
http.createServer( app ).listen(
    app.get("port"),
    function(){
        console.log("server is running in port ", app.get("port"));
    }
)

If you call the livereload BEFORE the session config, all will seems to work but the cookie will not persist. This was a tricky bug and I lost a full day into it. I hope this help somebody.

Share:
11,137
ac360
Author by

ac360

Updated on July 04, 2022

Comments

  • ac360
    ac360 almost 2 years

    In my production app, saving data to a session then redirecting is completely unreliable. A console.log after saving the session shows the data has been attached. Then on redirect, another console.log shows that the session has been reset. Every 3-5 tries, the session will persist across the redirect, but it is mostly unreliable. In my development app this code works flawlessly...

    • I've tried changing the version of express-session • I've tried moving the static folder above the session middleware in server.js • I've tried using req.session.save()

    UPDATE ****** This is a known issue with the session middleware: https://github.com/expressjs/session/pull/69

    Here is my server.js

    // Module Dependencies
    var express = require('express');
    var app = express();
    var mongoose = require('mongoose');
    var bodyParser = require('body-parser');
    var session = require('express-session');
    var favicon = require('serve-favicon');
    var methodOverride = require('method-override');
    
    // Set Environment from ENV variable or default to development
    var env = process.env.NODE_ENV = process.env.NODE_ENV || 'development';
    var config = require('./config/config');
    
    // Set Port
    var port = process.env.PORT || config.app.port;
    
    // Connect to our MongoDB Database
    // mongoose.connect(config.db);
    
    // set the static files location /public/img will be /img for users
    app.use(express.static(__dirname + '/public'));
    
    // Express Session
    app.use(session({
        secret: 'asfasfa3asfa',
        resave: true,
        saveUninitialized: true,
        cookie: {
            secure: false,
            maxAge: 2160000000
        }
    }));
    
    // Favicon
    app.use(favicon(__dirname + '/public/img/favicon.ico'));
    
    // Set Jade as the template engine
    app.set('views', './app/views');
    app.set('view engine', 'jade');
    
    // Get req.body as JSON when receiving POST requests
    app.use(bodyParser.json()); // parse application/json 
    app.use(bodyParser.json({
        type: 'application/vnd.api+json'
    })); // parse application/vnd.api+json as json
    app.use(bodyParser.urlencoded({
        extended: true
    })); // parse application/x-www-form-urlencoded
    
    // override with the X-HTTP-Method-Override header in the request. simulate DELETE/PUT
    app.use(methodOverride('X-HTTP-Method-Override'));
    
    // routes ==================================================
    require('./app/routes')(app); // pass our application into our routes
    
    // start app ===============================================
    app.listen(port);
    console.log('****** App is now running on port ' + port + ' ******'); // shoutout to the user
    exports = module.exports = app; // expose app
    

    Here is the controller where the session is being saved:

    // Module dependencies.
    var config = require('../../config/config');
    
    // Render Either Home Page or Dashboard Page If User is Logged In
    var index = function(req, res) {
    
        console.log("Session At Home Page: ", req.session)
    
        if (req.session.user) {
            res.render('dashboard');
        } else {
            res.render('home');
        }
    };
    
    
    // Handle Authentication Callback
    var callback = function(req, res) {
        // Get Access Token via Service-SDK
        Service.getAccessToken(req, function(error, tokens) {
    
            if (error) {
                console.log(error);
                return res.redirect('/');
            }
    
            // Otherwise, Save User Data & API Tokens To Session
            req.session.regenerate(function(err) {
                req.session.user = tokens.user_id;
                req.session.access_token = tokens.access_token;
                req.session.client_token = tokens.client_token;
                req.session.save(function(err) {
                    console.log("Session Before Redirect: ", req.session);
                    res.redirect('/');
                })
            });
        });
    };
    
    module.exports = {
        index: index,
        callback: callback
    };
    

    My Routes

    app.get('/auth/service/callback', application.callback)
        app.get('/logout', application.logout);
        app.get('/', application.index);
    
  • joshperry
    joshperry over 9 years
    Wow! Thank you for posting this. I lost almost a full day as well!
  • mdupls
    mdupls about 9 years
    I'm a bit confused - was the OP having an issue with livereload? His question does not mention the use of livereload.
  • Thiago Mata
    Thiago Mata about 9 years
    Based in what the OP says "This is a known issue with the session middleware: github.com/expressjs/session/pull/69" probably the bug what he was facing was NOT the livereload bug. The livereload bug it is show as a session error. So, besides this is not the fix what the OP was looking for, I believe that will help some people that will come to this page because this liverload + session bug.