Michael Michael - 2 months ago 17
Node.js Question

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"


Answer

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);
    }

});
Comments