menu

How to Manage Session using Node.js and Express

Session handling in any web application is very important and is a must-have feature, without it, we won’t be able to track user and it’s activity.

In this article, I am going to teach you how to handle Session in Node.js. We will use express as a framework and various other modules such as body-parser to handle form data.

YOUTUBE DEMO DOWNLOAD

At the time of writing article, the latest version of Express is 4.16.4.

What we are buiding

To demonstrate Session handling in Node, I have developed a basic Log-in and log-out System. In this User can log-in by providing their email, and that email will be used for further Session tracking. Once User log-out, Session will be destroyed and User will be redirected to the home page.

Creating Node Project

Let’s create a new Node project. Create a new folder and switch to it using the terminal.

Run this command to create a new Node project.

npm init --y

This command will create a new package.json file. Let’s install the required dependency.

npm install --save express express-session body-parser

Once the dependencies are installed, we can proceed to code our app.

If you are new to Node and Express then you won’t regret taking our Node course. Its FREE!

How to use Express Session ?

Before heading to actual code, i want to put few words about express-session module. to use this module, you must have to include express in your project. Like for all packages, we have to first include it.

server.js
const express = require('express');
const session = require('express-session');
const app = express();

After this, we have to initialize the session and we can do this by using following.

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

Here ‘secret‘ is used for cookie handling etc but we have to put some secret for managing Session in Express.

Now using ‘request‘ variable you can assign session to any variable. Just like we do in PHP using $_SESSION variable. for e.g

var sess;
app.get('/',function(req,res){
    sess=req.session;
    /*
    * Here we have assign the 'session' to 'sess'.
    * Now we can create any number of session variable we want.
    * in PHP we do as $_SESSION['var name'].
    * Here we do like this.
    */

    sess.email; // equivalent to $_SESSION['email'] in PHP.
    sess.username; // equivalent to $_SESSION['username'] in PHP.
});

After creating Session variables like sess.email , we can check whether this variable is set or not in other routers and can track the Session easily.

Tracking session in global variable won’t work with multiple users. This is just for the demonstration.

Project Structure

We are going to put all of Server side code in the server.js file. Front-end code will be placed inside the views folder.
session directory

Here is our Server side code.

server.js
const express = require('express');
const session = require('express-session');
const bodyParser = require('body-parser');
const router = express.Router();
const app = express();

app.use(session({secret: 'ssshhhhh',saveUninitialized: true,resave: true}));
app.use(bodyParser.json());      
app.use(bodyParser.urlencoded({extended: true}));
app.use(express.static(__dirname + '/views'));

var sess; // global session, NOT recommended

router.get('/',(req,res) => {
    sess = req.session;
    if(sess.email) {
        return res.redirect('/admin');
    }
    res.sendFile('index.html');
});

router.post('/login',(req,res) => {
    sess = req.session;
    sess.email = req.body.email;
    res.end('done');
});

router.get('/admin',(req,res) => {
    sess = req.session;
    if(sess.email) {
        res.write(`<h1>Hello ${sess.email} </h1><br>`);
        res.end('<a href='+'/logout'+'>Logout</a>');
    }
    else {
        res.write('<h1>Please login first.</h1>');
        res.end('<a href='+'/'+'>Login</a>');
    }
});

router.get('/logout',(req,res) => {
    req.session.destroy((err) => {
        if(err) {
            return console.log(err);
        }
        res.redirect('/');
    });

});

app.use('/', router);

app.listen(process.env.PORT || 3000,() => {
    console.log(`App Started on PORT ${process.env.PORT || 3000}`);
});

In the code shown above, there are four routers. First, which render the home page, the second router is used for login operation. We are not doing any authentication here for the sake of simplicity.

The third router is used for admin area where the user can only go if he/she is log-in. The fourth and the last router is for session destruction.

Each router checks whether the sess.emailvariable is set or not and that could be set only by logging in through front-end. Here is my HTML code which resides in views directory.

views/index.html
<html>
<head>
<title>Session Management in NodeJS using Node and Express</title>
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script>
$(document).ready(function(){
    var email,pass;
    $("#submit").click(function(){
        email=$("#email").val();
        pass=$("#password").val();
        /*
        * Perform some validation here.
        */
        $.post("/login",{email:email,pass:pass},function(data){
            if(data==='done') {
                window.location.href="/admin";
            }
        });
    });
});
</script>
</head>
<body>
<input type="text" size="40" placeholder="Type your email" id="email"><br />
<input type="password" size="40" placeholder="Type your password" id="password"><br />
<input type="button" value="Submit" id="submit">
</body>
</html>

In jQuery code, we are calling our Router ‘/login’ and redirecting it to the ‘admin‘ if log-in is successful, you can add validation to fields as per your requirement, for demo purpose i have not added any.

The Bug Alert!

As I have mentioned earlier, using a global variable for the session won’t work for multiple users. You will receive the same session information for all of the users.

So how do we solve this? By using a session store.

We save every session in the store so that one session will belong to the one user only. I have explained and build session store using Redis in this article.

For the quick reference, he is how we can extend the code shown above using Redis as a session store.

First, you need to install Redis on your computer. Click here to learn how to install Redis.

Then, install these dependencies in your project.

npm i --S redis connect-redis

Here is the codebase after upgrading it to support Redis.

server.js
/*
 * Manage Session in Node.js and ExpressJS
 * Author : Shahid Shaikh
 * Version : 0.0.2
*/

const express = require('express');
const session = require('express-session');
const bodyParser = require('body-parser');
const redis = require('redis');
const redisStore = require('connect-redis')(session);
const client  = redis.createClient();
const router = express.Router();
const app = express();

app.use(session({
    secret: 'ssshhhhh',
    // create new redis store.
    store: new redisStore({ host: 'localhost', port: 6379, client: client,ttl : 260}),
    saveUninitialized: false,
    resave: false
}));

app.use(bodyParser.json());      
app.use(bodyParser.urlencoded({extended: true}));
app.use(express.static(__dirname + '/views'));

router.get('/',(req,res) => {
    let sess = req.session;
    if(sess.email) {
        return res.redirect('/admin');
    }
    res.sendFile('index.html');
});

router.post('/login',(req,res) => {
    req.session.email = req.body.email;
    res.end('done');
});

router.get('/admin',(req,res) => {
    if(req.session.email) {
        res.write(`<h1>Hello ${req.session.email} </h1><br>`);
        res.end('<a href='+'/logout'+'>Logout</a>');
    }
    else {
        res.write('<h1>Please login first.</h1>');
        res.end('<a href='+'/'+'>Login</a>');
    }
});

router.get('/logout',(req,res) => {
    req.session.destroy((err) => {
        if(err) {
            return console.log(err);
        }
        res.redirect('/');
    });

});

app.use('/', router);

app.listen(process.env.PORT || 3000,() => {
    console.log(`App Started on PORT ${process.env.PORT || 3000}`);
});

If you notice in the code shown above, we have removed the global variable. We are using Redis to store our session instead. Try this multiple users and you should see unique session for each user.

I highly recommend following this article for more detailed information.

How to run example code

Download code and extract the zip file. Open your command prompt or Terminal and switch to the directory. Install dependency first by using.

npm install

Then run code using

node server.js

Visit localhost:3000 to view the app.

Session Using Node and Redis

Conclusion:

Like I mentioned session is very important for any web application. Node.js allows us to create an HTTP server and HTTP is a stateless protocol. It stores no information about previous visit and Express solves this problem very beautifully.

Further reading

Nodejs tutorials
Node.js MySQL Tutorial
Programming a Voice Controlled Drone Using Node and ARDrone