This tutorial explains how to use ExpressJS Session Stores using MongoDB and PostgreSQL.
In one of our previous posts we saw how to work with sessions in ExpressJS app. In that example we made use of memory as the session store. We also mentioned that we can replace memory with other session stores like MongoDB, Redis, MySQL, FileSystem and so on. In this post we will explore that further and show how to use MongoDB and PsotgreSQL as the session stores.
Why : ExpressJS Session Stores as DataBase?
Why do we need to store the session in an external DB?. In application deployed on different machines/nodes keeping the session data in memory will make the session data local to that machine/node. So if the request is served from a different machine/node then the session is not available for the user.
In order to avoid this issue, we store the session data in an external storage like MySQL, MonogDB and other DBs. This is very common practice to store the session data in DB and distribute among the different servers to avoid and loss of session data if any one of the server is down.
MongoDB Session Store
To use MongoDB as the session store we would have to install connect-mongo package along with the existing driver to connect to MongoDB. Connect-mongo is one of the popular and well tested ExpressJS middleware for storing the sessions.
Let us initialize the app and install the required packages. In the below code we are installing the following packages:
- Mongodb
- connect-mongo
- express
- express-session
$> mkdir mongodb-session-store $> cd mongodb-session-store $> npm init Press ^C at any time to quit. name: (mongodb-session-store) version: (1.0.0) description: sample using mongodb as session store entry point: (index.js) test command: git repository: keywords: author: mohamed sanaulla license: (ISC) About to write to G:\node\mongodb-session-store\package.json: { "name": "mongodb-session-store", "version": "1.0.0", "description": "sample using mongodb as session store", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "author": "mohamed sanaulla", "license": "ISC" } Is this ok? (yes) $> npm install --save mongodb $> npm install --save connect-mongo $> npm install --save express $> npm install --save express-session
Now let us create a simple express app which makes use of sessions. This example can be found in the post here, copying the same for this tutorial. Subsequently we will replace the memory session storage with MongoDB.
var express = require('express'); var session = require('express-session'); var app = express(); var sessionOptions = { secret: "secret", resave : true, saveUninitialized : false }; app.use(session(sessionOptions)); app.get("/", function(req, res){ if ( !req.session.views){ req.session.views = 1; }else{ req.session.views += 1; } res.json({ "status" : "ok", "frequency" : req.session.views }); }); app.listen(3300, function (){ console.log("Server started at: http://localhost:3300"); });
One of the options in the session options is specifying the store. We can provide the new store in the store
property of the sessionOptions
object. In order to connect to MongoDB We would also have to provide it with an existing connection object or provide it with the connection URL i.e parameters required to establish connection to MongoDB. Below is the code with MongoDB as the session store:
var express = require('express'); var session = require('express-session'); var MongoStore = require('connect-mongo')(session); var app = express(); var sessionOptions = { secret: "secret", resave : true, saveUninitialized : false, store: new MongoStore({ url:"mongodb://localhost/test", //other advanced options }) }; app.use(session(sessionOptions)); app.get("/", function(req, res){ if ( !req.session.views){ req.session.views = 1; }else{ req.session.views += 1; } res.json({ "status" : "ok", "frequency" : req.session.views }); }); app.listen(3300, function (){ console.log("Server started at: http://localhost:3300"); });
Before running the application make sure you have installed mongodb and the monogdb daemon i.e monogd is running. The parts of the code that has changed has been highlighted above and its a minimal change.
To confirm that we are indeed writing the session data to MongoDB, load the application http://localhost:3300/ in the browser a few times and then connect to mongodb and run the below commands:
> show collections scores sessions students system.indexes system.profile tasks > db.sessions.find().pretty() { "_id" : "dTzBBxq8UTuS-aGuivY1iqgiITaEcJdz", "session" : "{\"cookie\":{\"originalMaxAge\":null,\"expires\":null,\"httpOnly\":true,\"path\":\"/\"},\"views\":80}", "expires" : ISODate("2015-09-27T03:30:55.179Z") }
A collection by name sessions is created where each document represents a session data as shown in the highlighted code above.
PostgreSql Session Store
Now let us see how we can use PostgreSql as the session store. It involves a bit of setup in the PostgreSql. We would have to create the session
table in the db. The structure of the table is provided with connect-pg-simple
node package. Lets first install that package and then look at the table structure. Below are the commands we run to create a new app for this and install relevant packages.
G:\node>mkdir postgres-session-store G:\node>cd postgres-session-store G:\node\postgres-session-store>npm init Press ^C at any time to quit. name: (postgres-session-store) version: (1.0.0) description: Demo to use PostgreSql as session store entry point: (index.js) test command: git repository: keywords: author: mohamed sanaulla license: (ISC) About to write to G:\node\postgres-session-store\package.json: { "name": "postgres-session-store", "version": "1.0.0", "description": "Demo to use PostgreSql as session store", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "author": "mohamed sanaulla", "license": "ISC" } Is this ok? (yes) G:\node\postgres-session-store>npm install --save express G:\node\postgres-session-store>npm install --save express-session G:\node\postgres-session-store>npm install --save connect-pg-simple
The session table structure can be found in the path: node_modules/connect-pg-simple/table.sql
and the structure of the table is as given below:
CREATE TABLE "session" ( "sid" varchar NOT NULL COLLATE "default", "sess" json NOT NULL, "expire" timestamp(6) NOT NULL ) WITH (OIDS=FALSE); ALTER TABLE "session" ADD CONSTRAINT "session_pkey" PRIMARY KEY ("sid") NOT DEFERRABLE INITIALLY IMMEDIATE;
Run the above sql to create the table in your Postgres DB. We are going to use postgres
db.
Let us use the same express app code which we used at the start of this article. We are repeating the code here for your ease:
var express = require('express'); var session = require('express-session'); var app = express(); var sessionOptions = { secret: "secret", resave : true, saveUninitialized : false }; app.use(session(sessionOptions)); app.get("/", function(req, res){ if ( !req.session.views){ req.session.views = 1; }else{ req.session.views += 1; } res.json({ "status" : "ok", "frequency" : req.session.views }); }); app.listen(3300, function (){ console.log("Server started at: http://localhost:3300"); });
Let us update the above code to declare PostgreSql session store as shown below:
var express = require('express'); var session = require('express-session'); var PostgreSqlStore = require('connect-pg-simple')(session); var app = express(); var sessionOptions = { secret: "secret", resave : true, saveUninitialized : false, store : new PostgreSqlStore({ /* connection string is built by following the syntax: postgres://USERNAME:PASSWORD@HOST_NAME:PORT/DB_NAME */ conString: "postgres://postgres:postgres@localhost:5433/postgres" }) }; app.use(session(sessionOptions)); app.get("/", function(req, res){ if ( !req.session.views){ req.session.views = 1; }else{ req.session.views += 1; } res.json({ "status" : "ok", "frequency" : req.session.views }); }); app.listen(3300, function (){ console.log("Server started at: http://localhost:3300"); });
In the above code the highlighted parts are the ones which set the session store as PostgreSql. Let us run the application and load the URL http://localhost:3300/ multiple times. Then execute the below query in Postgres to check the data in the session
table:
select * from session;
And the output:
Conclusion
In this article we saw how we can make use of ExpressJS Session Store as MongoDB and Postgres to store the session data. This is very useful when the application is distributed across multiple nodes. In similar ways we can use Redis, LevelDB and other external stores to store session data. If you have any questions, please write it in the comments section.