If you’re building a web app with Node.js and Express, you’ve probably made it to the point where you need to implement user sessions in your application.
Typically, you’d whip up an npm install express-session
and end up with this sweet boilerplate code in your app.js
file:
const express = require('express'), app = express(), session = require('express-session'); app.use(session({ secret: process.env.SECRET_KEY, resave: false, saveUninitialized: true }));
Then you’d start adding middleware that makes use of web sessions like passport and connect-flash.
Now this is great but when deploying this code to a production environment your web app will start to leak memory and run into performance issues.
Why? Because express-session by default uses a MemoryStore
(in-memory key-value store for storing session data) implementation that is only designed for development environments.
It can’t scale well beyond a single process and will make your application slower (more on how sessions work if you’re interested here).
In fact, the express-session module will emit a warning when you try to use it in a production environment. On lines 152-153 of the index.js
file in express-session (as of release version 1.15.6):
// notify user that this store is not // meant for a production environment /* istanbul ignore next: not tested */ if ('production' == env && store instanceof MemoryStore) { console.warn(warning); }
At this point you have a few options. A good alternative is to use something like Redis and a node module for integrating it into the session middleware.
However, this requires additional setup in both your development and production machines. You’d have to install Redis (or whatever memory store you’d be using), configure it, test it, etc.
But if you are already using MongoDb for storage then your solution can be as simple as running npm install connect-mongo
and adding the following to your code:
const MongoStore = require('connect-mongo')(session); app.use(session({ store: new MongoStore({ url: process.env.DATABASE_URL }), secret: process.env.SECRET_KEY, resave: false, saveUninitialized: false, cookie: { maxAge: 1000 * 60 * 60 * 24 * 7 * 2 // two weeks } }));
It’s as easy as requiring the module, creating a new MongoStore
and re-using the database connection string (process.env.DATABASE_URL
) for your MongoDb instance.
connect-mongo will store your user sessions in your db in a collection named sessions
and takes care of removing them based on the maxAge
of the cookie configuration for the session.
You can now focus on writing your application logic instead of deployment and production concerns, which is great if you just want to get an MVP out the door quick and test the market.
Performance might also be comparable to something like Redis too (don’t quote me on that, though).