Getting Started With Express 4.x – Session/Cookie/CSRF – Tutorial 7

In this blog post, we will see some of the most used middleware in express when building a website namely Session, Cookie and CSRF.

Session with express

To use session with express we need to install this module https://github.com/expressjs/session

To start install the module first

npm install express-session --save

Next in your app.js you need to require the session module

var session = require('express-session');

Next add session as a middle ware, make sure to add it after cookieParser() just to be save

app.use(session({secret: 'any secret key'});

After this session would be added to the request variable and it can be used in any routes or middleware.
Here is a small example of using it

router.get('/', function (req, res) {
    if (!req.session) {
        req.session.count = 1;
    } else {
        req.session.count++;
    }
    res.send('setting session');
});
router.get('/count', function (req, res) {
    if (!req.session.count) {
        req.session.count = 0;
    }
    res.send('value in session ' + req.session.count);
});
router.get('/destroy', function (req, res) {
    req.session.destroy();
    res.send('session destroyed');
});

This is how the default session is stored.
Untitled
The expiry of this session is “Session” so it will go away as soon as browser closes.

app.use(session({secret: 'any secret key', cookie: {maxAge: 60000}}));

In the above we have specified maxAge of cookie so session won’t expire on browser close.
Untitled
If you need to make the session cookie secure use below, but this requires are https connection.

app.use(session({secret: 'any secret key', cookie: {maxAge: 60000,secure:true}}));

Since current session implementation uses browser cookies, it is not scalable and cannot store large amount of data.
It is also possible to mongodb based session storage using https://github.com/kcbanner/connect-mongo
Here is how to use it

var session    = require('express-session');
var MongoStore = require('connect-mongo')(session);

app.use(session({
    secret: settings.cookie_secret,
    store: new MongoStore({
      db : settings.db,
    })
  }));

Since mongodb can take time to do db operation, slight change is required in our code

router.get('/', function (req, res) {
    if (!req.session) {
        req.session.count = 1;
    } else {
        req.session.count++;
    }
    req.session.save(function(){
        res.send('setting session');
    });    
});

Rest everything is same.

<h2>CSRF with Express</h2>

CSRF or Cross Site Request Forgery is a security mechanism which is used to protect form submissions from 3rd party scripts.

The logic for this is quit simple, a _csrf parameter is set is cookie or session and same needs to be set as an input type hidden in forms. When the form is submitted, the _csrf token in cookie and form are validation. If match then all well else error is reported.

So here are steps to implement this, we will be using this module https://github.com/expressjs/csurf



in your app.js


var csrf = require('csurf')

Add the below code above routes

app.use(csrf())

// error handler
app.use(function (err, req, res, next) {
  if (err.code !== 'EBADCSRFTOKEN') return next(err)

  // handle CSRF token errors here
  res.status(403)
  res.send('session has expired or form tampered with')
})

//routes after this

Next we need to pass the csrf token to our view forms, in so in the render function we need to pass it

// pass the csrfToken to the view
app.get('/form', function(req, res) {
  res.render('send', { csrfToken: req.csrfToken() })
})
//and in view file
<form>
<input type="hidden" name="_csrf" value="{{csrfToken}}">

If this is implemented properly, you will see the _csft value filled up in your form (using inspect element) and if this value is not present in the form, you will get error “session has expired or form tampered with”