Session management in Express
One of the essential elements of the web application is session management. Without it we are not able to handle shopping carts, we are not able to give our users an ability to log in – use cases are endless. I was sure that there are ready-made libraries I can use to handle session variables, but I was not aware that this is that simple.
Let’s start with basics
I found that (judging by the downloads number) most used session management library is express-session. It can be configured to store session data in the Sequelize based database which is handy because I’m using Sequelize also in other parts of my project. I installed both elements like this:
npm install express-session connect-session-sequelize
There are much more connection libraries working with express-session, you can refer to the documentation to find one which will suit you best if you don’t like Sequelize.
Once installed, I adjusted my app.js file to initialize minimalistic session store.
//... var session = require('express-session'); //... app.set('trust proxy', 1) // trust first proxy app.use(session({ secret: 'mySecretPhrase', resave: false, saveUninitialized: true, cookie: { // secure: true // requires HTTPS connection } })) //...
As you can see, I added only a few lines of code, but this was enough – I noticed that now there is session cookie stored in my browser. Please note that I commented out “secure” in cookie section – this is working with HTTPS connections only and I don’t have such server configured yet.
Storing variables in the database
By default, express-session is storing session variables in MemoryStore which is not suitable for production sites and even for development if you want to test under heavy load. I decided that I will use Sequelize because I can start with SQLite database and switch to the more powerful engine when needed. Few more lines of code in app.js and I was ready to go:
//... var Sequelize = require('sequelize'); var SequelizeStore = require('connect-session-sequelize')(session.Store); //... var sequelizeSessionDB = new Sequelize( "database", "username", "password", { "dialect": "sqlite", "storage": "./sqliteDB/sessionStore.sqlite", operatorsAliases: false }); var mySessionStore = new SequelizeStore({ db: sequelizeSessionDB }); // make sure that Session tables are in place mySessionStore.sync(); // and finally adjustment to the session itself app.use(session({ secret: 'mySecretPhrase', resave: false, saveUninitialized: true, store: mySessionStore, cookie: { // secure: true // requires HTTPS connection } })) //...
The above was also working fine, and I decided to clean up a little bit and move session management to the separate module.
Final touches and tests
I started by creating the new module named /modules/sessionManagement.js, and I moved almost everything I already used in app.js:
var session = require('express-session'); var Sequelize = require('sequelize'); var SequelizeStore = require('connect-session-sequelize')(session.Store); var env = process.env.NODE_ENV || 'development' , config = require('./../config/config.'+env); var sequelizeSessionDB = new Sequelize(config.sessionDb.database, config.sessionDb.username, config.sessionDb.password, config.sessionDb.sequelizeParams); var mySessionStore = new SequelizeStore({ db: sequelizeSessionDB }); // make sure that Session tables are in place mySessionStore.sync(); module.exports = session({ secret: config.sessionSecret, resave: false, saveUninitialized: true, store: mySessionStore, cookie: { // secure: true // requires HTTPS connection } });
As you can see, there are configuration variables used, so I added this part to my configuration files:
config.sessionSecret = 'mySecretSessionKey'; config.sessionDb = { database: 'null', username: 'null', password: 'null', sequelizeParams: { dialect: 'sqlite', storage: './sqliteDB/sessionStore.sqlite', operatorsAliases: false } }
Finally, in my app.js file I ended up with only two lines of code instead of all I placed at the beginning:
//... var sessionManagement = require('./modules/sessionManagement'); app.use(sessionManagement); //...
Everything was working fine, so I decided to add new session variables on request start (in the /modules/tools.js file):
// in the body of onRequestStart //... if (req.session.startDate) { req.session.lastRequestDate = Date.now(); } else { req.session.startDate = Date.now(); req.session.lastRequestDate = Date.now(); } //...
The engine is initializing sessionStart variable once, and updates lastRequestDate on each request. I don’t really need such variables, but I wanted to check if the session is working and if the session state is indeed stored in SQLite database.
As I stated at the beginning – I was not aware that the implementation of session store would be so simple with the help of the above libraries. In literary few minutes, I was ready to start my work on user management. But this is the different story.
You can find this project source on GitHub.