Search code examples
node.jssessionexpresssequelize.jsexpress-session

After I set session to be stored in db there is a delay before it is registered. Node/Express/express-session,


After log in I want to redirict to /makeitem, which requires a session to open. This works, but after the log in form is submitted I get my error message and I have to refresh to enter the /makeitem. This worked perfectly fine before I started using connect-session-sequelize. The cookie gets stored in db.Sessions right away so that part works.

Why is this happening? Do I have to check for the session somewhere else in my middleware? How can I make it redirect without any hazzle? Am I missing something obvious?

Thank you, and please don't just link to docs, I've been looking at docs all day and they make my fairly new programmer brain hurt. I need som love and education.

SERVER.JS

'use strict';

var express = require('express');
var session = require('express-session');
var bodyParser = require('body-parser');
var cookieParser = require('cookie-parser');
var _ = require('underscore');
var app = express();

var db = require('./db.js');

// initalize sequelize with session store
var SequelizeStore = require('connect-session-sequelize')(session.Store);


// if heroku use that, else use 3000
var PORT = process.env.PORT || 3000;

app.use(cookieParser());

// Track logins with express session
app.use(session({
    secret: 'Magic mike',
    resave: true,
    saveUninitialized: false,
    store: new SequelizeStore({
        db: db.sequelize
    })
}));

// Make userId available in templates
app.use(function(req, res, next){
    res.locals.currentUser = req.session.userId;
    next();
});
....

ROUTES/INDEX.JS

var express = require('express');
var router = express.Router();
var _ = require('underscore');
var mid = require('../middleware/');
var db = require('../db.js');

.....

// POST /login
router.post('/login', function(req, res, next) {
    var body = _.pick(req.body, 'email', 'password');

    if (req.body.email && req.body.password) {
        db.user.authenticate(body).then(function(user) {
            req.session.userId = user.id;
            return res.redirect('makeitem');
        });
    } else {
        var err = new Error('All fields required.');
        err.status = 400;
        err.message = 'All fields required.';
        console.log(err.message);
        res.send(err.message);
    }

});
.....
    // GET /makeitem
router.get('/makeitem', mid.requiresLogin, function(req, res, next) {
    var body = _.pick(req.body, 'description', 'amount', 'purchased');

    return res.render('makeitem.pug');
});
....

MIDDLEWARE/INDEX.JS

 function loggedOut(req, res, next) {
    if (req.session && req.session.userId) {
        return res.redirect('/makeitem');
    } else {
        return next();
    }
}

function requiresLogin(req, res, next) {
    if (req.session && req.session.userId) {
        return next();
    } else {
        var err = new Error('You must be logged in to view this page');
        err.status = 401;
        return next(err);
    }
}

module.exports.loggedOut = loggedOut;
module.exports.requiresLogin = requiresLogin;

My relevant dependencies are:

  • "express": "^4.14.0"
  • "express-session": "^1.14.1"
  • "sequelize": "^3.5.1"
  • "connect-session-sequelize": "^3.1.0"
  • "sequelize": "^3.5.1"
  • "sqlite3": "^3.1.4"

Solution

  • This sounds very similar to the issue :

    Race Condition When Used With Passport

    Your best way of solving this would be :

    router.post('/login', function(req, res, next) {
        var body = _.pick(req.body, 'email', 'password');
    
        if (req.body.email && req.body.password) {
            db.user.authenticate(body).then(function(user) {
                req.session.userId = user.id;
    
                // Add this :
                req.session.save(function() {             
                    return res.redirect('makeitem');
                });
    
            });
        } else {
            var err = new Error('All fields required.');
            err.status = 400;
            err.message = 'All fields required.';
            console.log(err.message);
            res.send(err.message);
        }
    
    });