mweibel / connect-session-sequelize

Sequelize SessionStore for Express/Connect

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

SessionStore causes error on CSRF token

charles-dejager opened this issue · comments

I am using ExpressJS with csurf, express-session, and connect-session-sequelize. When I set up express-session with no store (ie use memstore) all works as it should. When I use connect-session-sequelize I get a

403 - ForbiddenError: invalid csrf token
at csrf (/Users/djagercd/dev/mm-edds/node_modules/csurf/index.js:113:19)

My config looks as follows:

// **session-connect.js**
const
    session = require('express-session'),
    sessionStore = require('connect-session-sequelize')(session.Store),
    {logger} = require('./logger');


function init(server, config, db) {
    const sequelizeSessionStore = new sessionStore({
        db: db.sequelize,
        checkExpirationInterval: config.session.expireInterval,
        expiration: config.session.expiration
    });

    // sequelizeSessionStore.sync();

    server.use(session({
        secret: config.session.secret,
        store: sequelizeSessionStore,
        resave: config.session.reSave,
        proxy: config.session.proxy,
        saveUninitialized: config.session.saveUninitialized
    }));

    // sequelizeSessionStore.sync();

}
// **index.js (main module of my server).**
'use strict';

const
    express = require('express'),
    bodyParser = require('body-parser'),
    {logger, expressErrorLogger, expressLogger} = require('./logger'),
    process = require('process'),
    routes = require('./routes'),
    db = require('./models'),
    cookieParser = require('cookie-parser'),
    path = require('path'),
    compression = require('compression'),
    helmet = require('helmet'),
    csrf = require('csurf'),
    session = require('./session-connect'),
    knex = require('./db'),
    server = express();

function shutDown() {
    logger.log('info', 'Shutting Down Server');
    db.sequelize.close()
        .then(result => {
            return knex.destroy();
        })
        .then(result => {
            return session.clear();
        })
        // .then(result => {
        //     return server.close();
        // })
        .then(result => {
            logger.log('info', 'Successful Shutdown');
            return true;
        })
        .catch(err => {
            logger.log('error', `Shutdown failed ${err.toString()}`);
            return false;
        })
}


module.exports = function () {
    let create,
        start;

    create = function (config) {

        const staticDir = path.join(__dirname, '..', 'public');
        // const csrfProtection = csrf();


        server.set('env', config.env);
        server.set('port', config.port);
        server.set('hostname', config.hostname);
        server.set('viewDir', config.viewDir);
        server.set('staticDir', staticDir);
        server.set('db', db);

        // Setup view engine
        server.set('view engine', 'ejs');
        server.set('views', server.get('viewDir'));

        // server.use(express.json);
        // server.use(express.urlencoded);
        server.use(helmet());
        server.use(helmet.xssFilter({setOnOldIE: true}));
        server.use(helmet.frameguard('deny'));
        server.use(helmet.hsts({maxAge: 7776000000, includeSubdomains: true}));
        server.use(helmet.hidePoweredBy());
        server.use(helmet.ieNoOpen());
        server.use(helmet.noSniff());
        server.use(helmet.noCache());

        server.use(bodyParser.json());
        server.use(bodyParser.urlencoded({extended: false}));

        server.use(express.static(staticDir));
        server.use(compression());
        server.use(cookieParser());
        server.use(expressLogger);

        // Setup session handling
        session.init(server, config, db);

        server.use(csrf({cookie: false}));


        server.use((req, res, next) => {
            res.locals.csrfToken = req.csrfToken();
            console.log(`req csrf: ${res.locals.csrfToken}`);
            res.locals.isAuthenticated = req.session.isLoggedIn;
            res.locals.current_user = req.session.current_user;
            res.locals.message = '';
            next();
        });

        routes.init(server);

        server.use(expressErrorLogger);
    };

    start = function () {

        const hostname = server.get('hostname'),
            port = server.get('port');

        server.listen(port, function () {
            logger.log('info', `Starting Server for ${server.get('env')} configuration`);
            logger.log('info', `Express server listening on: http://${hostname}:${port}`)
        });
    };


    return {
        create: create,
        start: start,
        shutDown: shutDown
    };
};

My login.ejs file does have the hidden input field called _csrf.

You help would be appreciated.

It'd be easiest if you create a quick repo with how to reproduce it. Is that possible?

@charles-dejager does your app work when you use server.use(csrf({cookie: true}));?