Manage session using Node.js and Express 4

Session handling in any web application is very important and must have thing, without it we won’t be able to track user and it’s activity. In my previous article i have explained Session handling in PHP.

In this article i am going to explain how to handle Session in ExpressJS 4 and above. Express 3 deprecate many dependencies like ‘bodyParser‘ , ‘logger‘ etc. Our code is written by taking consideration of latest Express JS framework.

YOUTUBE DEMO DOWNLOAD

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

To demonstrate Session handling in Node, i have developed small 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 home page.

Important !

If you are familiar with Express and using its in built body-parser and session, then it’s no more and you have to now install those dependencies separately.  Following are the dependencies which we have used for this System.

package.json
{
    "name": "Node-Express4-Session",
    "version": "0.0.1",
    "main": "server.js",
    "dependencies": {
        "body-parser": "^1.7.0",
        "ejs": "^1.0.0",
        "express": "^4.8.7",
        "express-session": "^1.7.6"
    }
}

Run

npm install

to install dependencies for the project.

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
var express = require('express');
var session = require('express-session');
var 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.

Project Directory Structure :

session directory

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

app.set('views', __dirname + '/views');
app.engine('html', require('ejs').renderFile);

app.use(session({secret: 'ssshhhhh'}));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: true}));

var sess;

app.get('/',function(req,res){
sess = req.session;
//Session set when user Request our app via URL
if(sess.email) {
/*
* This line check Session existence.
* If it existed will do some action.
*/

    res.redirect('/admin');
}
else {
    res.render('index.html');
}
});

app.post('/login',function(req,res){
  sess = req.session;
//In this we are assigning email to sess.email variable.
//email comes from HTML page.
  sess.email=req.body.email;
  res.end('done');
});

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

app.get('/logout',function(req,res){
req.session.destroy(function(err) {
  if(err) {
    console.log(err);
  } else {
    res.redirect('/');
  }
});

});
app.listen(3000,function(){
console.log("App Started on PORT 3000");
});

In code there are three routers. First which render the home page, second router is use for admin area where user can only go if he/she is log-in and third is to perform session destruction and logging out the user.

Each router checks whether the sess.email variable 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 Express4.2</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("http://localhost:3000/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.

How to run example code:

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

npm install

Then run code using

node server.js

Visit localhost:3000 to view the app.

Conclusion:

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

Shahid (UnixRoot) Shaikh

Hey there, This is Shahid, an Engineer and Blogger from Bombay. I am also an Author and i wrote a programming book on Sails.js, MVC framework for Node.js.

Related Posts

64 Comments

  1. Hi man !
    Thanks for this great post ! I’ve got an issue with session managing, if you got some minuts could you help me please ?
    I written some routes with app.get(). I’ve done an app.post for the login, and the mechanism works well (I’m going to auth my user by searching into a mongodb database). I then store his username in sess.username.
    But when the user then navigate to the other routes, and I check sess.username it’s always null.

    I’ve written sess = req.session; in the top of every routes dedicated code and then I checked the sess.username.

    Oh, and sess is a global variable.
    Do you see what is messing up ? Thanks in advance 🙂

    1. Hi Alex,
      Thanks for your posting your question.
      Programmatically your approach is correct. Before i put my comment on it, could you please verify that your app.use(session(–rest params–)) uses this resave: true.
      Thanks.

      1. Thanks for replying Shahid 🙂
        This value is true by default but I tried anyway to affect true to the resave option in session. I also tried to do a session.save function at login.
        Maybe in the new version of express-session it is impossible to bind a value to the session objet ? thus i didn’t noticed something like this into the express-session doc …

        1. I am facing the same problem.Did u got any solution ?/
          have u tried changing app.use(session.-) i.i another version of session? Plz let me know!!

    2. Alex, I realize this was a while back, but I’ll reply in hopes that it resolves someone stuck on a similiar problem. The reason your global variable sess is null is because its being reassigned for each request after it was initially set. The purpose of binding the session to the req variable is because its the only response-specific state being passed between the express middleware and routing.

  2. Nice Tut! Is there a better way to make {email, password, phone} more dynamic and match up destination structure?

    Thanks!

    1. To handle concurrent session , you need to create unique Session ID and give it to client once the session is set so that next time until they logout / close browser they need to pass that unique ID in every request they made to server and you need to check it in every router.

      1. Thanks for the reply.
        Actually what i mean to ask was, can 2 treads simultaneously access session object and corrupt it’s state ? and how to prevent that.

        I’m coming from servlet background, where session object is shared, so we synchronize it’s access.

      2. Hi Shahid,
        I am implementing the session handling for the first time. I am using NodeJs & express and Extjs for server and client side implementation respectively. The above reply of yours help me a lot. Thanks for that! However, I am struggling to send the sessionID fro client (ExtJs) back to server. Can you suggest me a way to do this? Also, if i am able to send that session ID somehow, What should i compare it with? req.sessionID?

        1. If you want to send Anything to Nodejs server, you can do it using GET or POST HTTP method. Now as per your concern i am not sure why you want to send Session ID which you got from back-end to front-end again ?

          1. Even I thought it was not needed to send the ID back to server and implemented it that way. But this reply of yours to “Arjun’s” query some days back, confused me slightly.

            “To handle concurrent session , you need to create unique Session ID and give it to client once the session is set so that next time until they logout / close browser they need to pass that unique ID in every request they made to server and you need to check it in every router”

            I am sorry if I asked something very obvious but as i have told u I am implementing this for the first time and so i want to make sure concurrent sessions are handled.

  3. Hello!

    How do I get to make this work with authFactory? Can’t seem to get any value for sess.email. It says it is undefined

    app.get(‘/api/auth/login/session’,function(req,res){
    sess = req.session;
    if(sess.email)
    {
    console.log(sess.personid);
    /*
    results.personid = req.body.personid;
    results.name = req.body..firstname;
    results.email = req.body..email;
    */

    }
    else
    {
    console.log(‘sess email is undefined’);
    }
    });

      1. Hey Shahid, I see where my problem is! I am not using php but express.js as my api. I am all new with angular but your tuts are amazing. I actually am doing a freelance project just from stuff I learned from you!

        Thanks!!

          1. Hello Shahid

            I am using purely js for my api (express) but when user tries to login user gets kicked out.

            //app.js
             .run(function ($rootScope, $location, authFactory) {
                $rootScope.$on("$routeChangeStart", function (event, next, current) {
                    $rootScope.authenticated = false;
                    authFactory.GetSession('session').then(function (results) {
                        if (results.personid) {
                            $rootScope.authenticated = true;
                            $rootScope.personid = results.personid;
                            $rootScope.name = results.firstname;
                            $rootScope.email = results.email;
                        } else {
                            var nextUrl = next.$$route.originalPath;
                            if (nextUrl == '/signup' || nextUrl == '/login') {

                            } else {
                                $location.path("/login");
                            }
                        }
                    });
                });
            });
            //serviceFactory
            app.factory('authFactory', ['$http', function($http) {

                //var urlBase = 'http://localhost:8001/api/auth/';
                var urlBase = 'http://localhost:8001/api/auth/';
                var authFactory = {};

                authFactory.LogIn= function () {
                return $http.post('http://localhost:8001/api/auth/login');
                };

                authFactory.LogOut= function (q) {
                return $http.get('http://localhost:8001/api/auth/logout');
                }; 

                authFactory.GetSession = function (q) {
                    return $http.post('http://localhost:8001/api/auth/login/session/');
                };

               
                authFactory.Signup = function (q) {
                    return $http.post(urlBase + q);
                };

               authFactory.get = function (q) {
                    return $http.get(urlBase + q).then(function (results) {
                        return results.data;
                    });
                };

                return authFactory;
            }]);

            //api.js
            app.post('/api/auth/login', function(req, res){
                sess=req.session;
               
                var email = req.body.email;
                var password = req.body.password;
               
                //In this we are assigning email to sess.email variable.
                //email comes from HTML page.
                sess.email = email;
                sess.password = password;
               
                connection.query('SELECT * FROM persons where email = "' + email + '" and password = "' + password + '"', req.params.id, function(err, rows, fields) {
                    if (err) {
                        console.error(err);
                        res.statusCode = 500;
                        res.send({
                            result: 'error',
                            err:    err.code
                        });
                    }
                    res.send(rows);
                });  
             
            });
    1. Every user who connect with your HTTP server gets a connection thread and Session is maintained for that thread. If you have code to demonstrate that its wrong then it would be awesome.

  4. How will your setup work among multiple node applications? I’m assuming since you haven’t configured any shared storage (such as Redis or similar) for your session, that the default memory store is used. If that’s the case – and requests are handled by different applications (running on different processes) or perhaps (if on AWS) by different EC2 instances – then none of the above will work.

    1. Yeah you are right. Above code was for handling session in simple web application. For shared instance we need storage like Redis or something to store session key. Will write tutorial on that. Thanks.

  5. Hi, Thanks for the great tutorial but I am facing an error. I am using express 4.0 and implementing session in routes/index.js

    In the post when I do,
    sess=req.session;
    sess.usr=req.body.username;

    I get error as – Cannot set property ‘usr’ of undefined

    I have also tried doing –
    var sess={usr:1,
    st:2};

    Still no luck.

    Kindly help me.

  6. HI ,

    Nice tutorial !
    Can you please update to manage more then one user login at the same time .When ever a new request comes the old session data is replace by the new request .
    code example
    app.post(‘/validate’,function(req,res){
    sess=req.session;
    sess.username=req.body.username});

    by the req.body.username i getting the username.

  7. hello,

    Thanks for sharing administration with Node.js and expressjs sessiones

    I have a question

    It has the following
    app.get(‘/logout’,function(req,res){
    req.session.destroy(function(err){
    if(err)console.log(err);
    res.redirect(‘/’);
    }
    });

    After removing the session is redirected to the root

    After being at the root , if I make a back in the browser displays the previous page which should not happen

    You know that makes this behavior?

    What would be the solution?

    I appreciate your time

    note :
    Before running app.get , I have a middleware where only verified if there is a session I make a next () ;
    otherwise I make a redirect to the root

    1. Hi,

      Previous page is also the Router and if you are doing validation of session in each router or in Middle ware then this should not happen.

      If session is inactive then redirect to home ( / ).

      Mail me code if you can.

      Thanks,
      Shahid.

    2. I’m facing a similar problem. Were you able to find a solution? If you did, could you please email it to me as well

  8. Hi Shahid,

    I have implemented passportjs for user authentication and authorization , I want to get the user details stored in session in angularjs(html not jade) frontend ?I don know how to move further Could you pls help me out ? I can see the browser cookie having the session userid but im not able to print the session details in index.js where I do my routing

    module.exports = function(passport){
    router.get(‘/’, isAuthenticated, function(req, res){

    var user = req.session.user;
    var a = req.user.username;
    var b = req.user.password;
    var c = req.user.emailid;
    console.log(a); // not printing in the console
    console.log(b); // not printing in the console
    console.log(c); // not printing in the console

    res.render(‘home’, { title: ‘User session Home’, user: req.user });

    });

  9. Shahid,
    I added the below 2 lines in app.js
    app.set(‘view engine’, ‘html’);
    app.engine(‘html’, ejs.renderFile);

    and tried fetching the json in html but cudn… Can you show a sample of how to get json in html ?
    (OR) do i convert the .html into .ejs ?

    1. try adding this

      app.engine(‘html’, require(‘ejs’).renderFile);

      make sure you have EJS installed.

      Then on routes,
      res.render(“home.html”,{ email : “[email protected]”});

  10. Shahid,

    I have this in my routes
    res.render(‘home.html’, { title: ‘User session Home’, user: req.user });

    this is how it displays when i hit the url
    Welcome

    This is my html code
    Welcome

  11. Hi Shahid ,

    I got the express session username in html without templating engine 🙂 Thank you so much for suggesting ejs. Now my issue is when i click logout btn the passport/express session isnt destroyed ,redirection to home doesn work and i also want to remove the username from the html.. im quite unclear abt logout routing whether im doing the right way or not . Your emailID pls !!

  12. hi man.

    i am from south korea.

    i read well your tutorial and it helped me a lot. (sorry i do not english well)

    can i ask one question?

    long time ago, i read a article for session, in the article, ‘cookie-parser’ was necessary to use session. look following example code.

    [psedo code]
    app.use(cookieParser(~~~)); // cookieparser is located before session for working always.
    app.use(session(~~~));

    but in your tutorial, you didn’t use cookie-parser.

    express or express session is changed about session mechanism?

  13. hey Shahid !!

    m trying to render a web page designed in polymer but unfortunately its is unable to inherit any of its data from polymer script if use normal express server . But i tried to do that with python it works good on that, can you please help me out to sort this issue. How can i run a normal polymer designed static page on Node sever other wise how to use Http server (in python : python -m http.server)

        1. I know that very well but its programmer who made that stack and session has to be always controlled by Server not UI.

          You need to view this tutorial to understand the working example.

  14. Override the session value.
    var express = require(‘express’);
    var session = require(‘express-session’);
    var sess;

    step:1

    router.post(“/login”, function(req, res) {
    var email = “[email protected]”;
    sess = req.session;
    sess.email = email;
    res.send({
    data : sess
    });
    });

    step:2
    router.post(“/update”, function(req, res) {
    var email = “[email protected]”;
    sess = req.session;
    sess.email = reqData.email;
    res.send({
    data : sess
    });
    });

    step:3

    router.get(“/check”, function(req, res) {
    sess = req.session;
    var email = sess.email;
    console.log(email);
    //Here display first value.([email protected])
    //how can i get email value ([email protected])?
    });

    How can I override the session value?

  15. Hi shahid, I tried your tutorial, i have app.js as my main file. I want to write the rest of the code in another file in controllers. But when i try to run it, it gives me an error “cannot read property of undefined”. Please help me out

  16. Hi shahid,iam new to nodejs.I tried this tutorial it is working well but my problem is i made my own html page and i styled it with css,now i placed my stylesheet also in views folder and i gave that path in my html page but when i visit localhost:3000 only the plain html page is displaying,css is not supporting.so how can i display the page along with css.Please help me out.

  17. vn, how the fuck you supposed this should work?
    Like, author will leave all his tasks and start working on your problem? which is absolutely not relevant to this topic.
    are you retarded or what??

  18. thanks dude,its been amazing learning from you,I have finally learnt how to manage session using Node.js

  19. Hey shahid first of all thanks for this amazing tutorial. My problem is when my browser close then my session expire i m using sess.cookie.maxAge = false ; but it’s not work Thanks In advance.

  20. Hi,

    If Node Server stops due to some mongodb error or else, then session expires/out, so the user click any other route, the page will redirect to login…how can i fix this ?

    Thanks

  21. Hi

    I have links:
    res.write(“‘ Pear'” + “Pear“);

    app.get(‘/addtocart/:pid’, function (req, res, next) {
    sess = req.session;
    if (sess.cart === undefined)
    sess.cart = [];
    var phoneId = req.params.pid;
    console.log(phoneId);
    //alert(phoneId);
    sess.cart.push(phoneId);
    console.log(“cart contains : “+sess.cart.length);
    next();
    //res.redirect(‘/products’);
    });

    this code adds to cart , but it redirects away
    how to stay on products page?

    regards
    and thanks for good tutorial

Leave a Reply

Your email address will not be published. Required fields are marked *