Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Node, express.session as middleware does not set cookie

this question is related to NodeJS + Express - Apply session middleware to some routes which I first thought would solve my problem. But it did not.

I'm trying to build a site where the first default-page show the user info about the site needing to use cookies and gives him the possibility to accept this. Therefore I do not want the server to send a set-cookie header until after the user has given their acceptance.

As in the solution to the question above I now try and insert the session as a middleware only to the routes that should have it. The problem is that doing so I never get any set-cookie header from the server. Checked this with Fiddler.

My code looks like this (only the relevant parts):

var express = require('express');
var app = express();
var session      = require('express-session');
var mongoose = require('mongoose');
var configDB = require('./config/database.js');
var mongoStore = require('connect-mongo')(session);

mongoose.connect(configDB.url);

var mongoSessionStore = new mongoStore({
    mongoose_connection: mongoose.connections[0]
});

.
.
.

var sessionMiddleware = session({
    secret: 'secret',
    store: mongoSessionStore,
    key:    'express.sessionID',
    cookie: {domain: 'the-domain', path: '/', httpOnly: true, secure: false, maxAge: null },
    saveUninitialized: false,
    resave: false   
});

require('./app/routes.js')(app, passport, sessionMiddleware);

And the routes looks like this, in seperate file:

module.exports = function(app, passport, sessionMiddleware) {

    app.get('/', loginIsLoggedIn, function(req, res) {
        res.render('cookie.ejs');
    });


    app.post('/', function(req, res) {
        if(req.body.cookieAnswer == "Accept"){
            res.redirect('/login');
        } else {
            res.render('cookie.ejs', {cookieMsg: req.body.cookieAnswer});
        }
    });

    app.get('/login', sessionMiddleware, loginIsLoggedIn, function(req, res) {
        res.render('login.ejs', {successMsg: res.locals.success_message, errorMsg: res.locals.error_message});
    });


    app.post('/login', sessionMiddleware, passport.authenticate('local-login', {
        successRedirect : '/auth',
        failureRedirect : '/login',
        failureFlash : true // allow flash messages
    }));

I hoped that when the sessionmiddleware is called the first time, when processing get 'login.ejs', that it would generate the set-cookie header in the response but there is something I'm missing here.

If I set up middleware like this:

app.use(session({
    secret: 'secret',
    store: mongoSessionStore,
    key:    'express.sessionID',
    cookie: {domain: 'the-domain', path: '/', httpOnly: true, secure: false, maxAge: null },
    saveUninitialized: false,
    resave: false   
}));

The set-cookie header is sent directly when entering the site, but I don't want that.

Appreciate any help!

like image 724
northmoose Avatar asked Feb 19 '15 09:02

northmoose


People also ask

How do you set an express session cookie?

var cookieSession = require('cookie-session') var express = require('express') var app = express() app. use(cookieSession({ name: 'session', keys: ['key1', 'key2'] })) // Update a value in the cookie so that the set-cookie will be sent. // Only changes every minute so that it's not sent with every request.

Does Express session use cookies?

express-session stores only a session identifier on the client within a cookie and stores the session data on the server, typically in a database.

Does Express session need cookie-parser?

Since version 1.5. 0, the cookie-parser middleware no longer needs to be used for this module to work. This module now directly reads and writes cookies on req/res. Using cookie-parser may result in issues if the secret is not the same between this module and cookie-parser .

How do I use cookies and sessions in node js?

Cookies and sessions make the HTTP protocol stateful protocol. Session cookies: Session cookies are the temporary cookies that mainly generated on the server-side. The main use of these cookies to track all the request information that has been made by the client overall particular session.


1 Answers

I found the answer in the documentation of .use.

I could not use the solution given to question NodeJS + Express - Apply session middleware to some routes since the ordering of my middlewares got messed up then.

So what I needed to do was point out which routes should use the middlewares when declaring the app.use(... In may case I wanted the middleware for session to act on all routes except the '/' so my new declaration of the middleware looks like this:

var routesArray = ['/login', '/auth', '/signup', '/email', '/chPassW', '/logout', '/snapshot'];

app.use(routesArray, session({
    secret: 'secret',
    store: mongoSessionStore,
    key:    'express.sessionID',
    cookie: {domain: 'the-domain', path: '/', httpOnly: true, secure: false, maxAge: null },
    saveUninitialized: false,
    resave: false   
}));
like image 100
northmoose Avatar answered Sep 27 '22 16:09

northmoose