Skip to main content

How to creating and managing sessions in Node.js and Express.js for Beginners

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

In Node.js sessions work at application level. When you initialize a session handler object as a middleware in ExpressJS, the request object will share an instance of such handler with all the routes of your application.

The express-session module works in this way. Once a session handler has been created, we can add or remove session variables by simply manipulating a JavaScript object.

Though this module uses the server's memory as its default storage mechanisms, it's often preferable a database-based approach on a production environment due to the volatility of the default mechanism. For example, it becomes difficult to track user actions or, say, to save a shopping cart for later use when your session data are stored in memory. When you restart your app, all data saved in memory are gone forever.

We can use MongoDB as session storage. First, we need to include the requested modules.

npm install express-session --save
npm install connect-mongodb-session --save

In MongoDB we need to create a collections for our sessions. For the sake of simplicity we can call it sessions. Then we can reference the newly installed modules in our app.


'use strict';

const express = require('express');
const session = require('express-session');
const MongoDBStore = require('connect-mongodb-session')(session);


Configuring the MongoDB store is simple: just pass the database connection URL and the name of the collection to the constructor.


const store = new MongoDBStore({
    uri: 'mongodb://username:password@127.0.0.1/test',
    collection: 'sessions'
});

At this point we can set up our session middleware.


const app = express();
app.use(session({
    secret: 'secret token',
    resave: false,
    saveUninitialized: true,
    unset: 'destroy',
    store: store,
    name: 'session cookie name',
    genid: (req) => {
        // Returns a random string to be used as a session ID
    }
}));

Take a look now at the implementation of a simple authentication flow.


app.post('/login', async (req, res) => {
    try {
        let user = await db.users.findOne({email: req.body.email});
        if(user !== null) {
            req.session.user = {
                  email: user.email,
                  name: user.name
            };
            res.redirect('/account');
        } else {
           // Login error
        }
    } catch(err) {
        res.sendStatus(500);
    }
});

When a user successfully logs in, we store his credentials in the session object. This object is shared among all routes and we can pass it to views.


app.get('/account', (req, res) => {
    if(!req.session.user) {
        res.redirect('/login');
    } else {
        res.render('account', {user: req.session.user});
    }
});

Here if the reference is not present in our session object, it simply means that our visitors are not logged in.

To remove a session variable, we can use the delete operator.


app.get('/logout', (req, res) => {
    if(req.session.user) {
        delete req.session.user;
        res.redirect('/login');
    } else {
        res.redirect('/');
    }        
});

It's clear now that in its essence session management is simply a matter of getting/setting/deleting a JavaScript object's properties.

As we said earlier, in ExpressJS sessions are created at application level. This means that when you launch your app, you're creating a brand new session handler for the whole Node process. Instead, in PHP sessions are created by request. When you hit a page which has session_start() in it, PHP checks whether the browser has already stored the session token. If so, it continues with the current session, otherwise it starts a new session.

Suppose now that you're implementing a shopping cart in Express. If you set the cart's variable at the very beginning, you'll simply get the unwanted result of having a single shopping cart shared among all the users of your website. In other words, session variables must be set locally after certain user's actions.

Comments

Popular posts from this blog

How to use Ngx-Charts in Angular ?

Charts helps us to visualize large amount of data in an easy to understand and interactive way. This helps businesses to grow more by taking important decisions from the data. For example, e-commerce can have charts or reports for product sales, with various categories like product type, year, etc. In angular, we have various charting libraries to create charts.  Ngx-charts  is one of them. Check out the list of  best angular chart libraries .  In this article, we will see data visualization with ngx-charts and how to use ngx-charts in angular application ? We will see, How to install ngx-charts in angular ? Create a vertical bar chart Create a pie chart, advanced pie chart and pie chart grid Introduction ngx-charts  is an open-source and declarative charting framework for angular2+. It is maintained by  Swimlane . It is using Angular to render and animate the SVG elements with all of its binding and speed goodness and uses d3 for the excellent math functio...

Understand Angular’s forRoot and forChild

  forRoot   /   forChild   is a pattern for singleton services that most of us know from routing. Routing is actually the main use case for it and as it is not commonly used outside of it, I wouldn’t be surprised if most Angular developers haven’t given it a second thought. However, as the official Angular documentation puts it: “Understanding how  forRoot()  works to make sure a service is a singleton will inform your development at a deeper level.” So let’s go. Providers & Injectors Angular comes with a dependency injection (DI) mechanism. When a component depends on a service, you don’t manually create an instance of the service. You  inject  the service and the dependency injection system takes care of providing an instance. import { Component, OnInit } from '@angular/core'; import { TestService } from 'src/app/services/test.service'; @Component({ selector: 'app-test', templateUrl: './test.component.html', styleUrls: ['./test.compon...

How to solve Puppeteer TimeoutError: Navigation timeout of 30000 ms exceeded

During the automation of multiple tasks on my job and personal projects, i decided to move on  Puppeteer  instead of the old school PhantomJS. One of the most usual problems with pages that contain a lot of content, because of the ads, images etc. is the load time, an exception is thrown (specifically the TimeoutError) after a page takes more than 30000ms (30 seconds) to load totally. To solve this problem, you will have 2 options, either to increase this timeout in the configuration or remove it at all. Personally, i prefer to remove the limit as i know that the pages that i work with will end up loading someday. In this article, i'll explain you briefly 2 ways to bypass this limitation. A. Globally on the tab The option that i prefer, as i browse multiple pages in the same tab, is to remove the timeout limit on the tab that i use to browse. For example, to remove the limit you should add: await page . setDefaultNavigationTimeout ( 0 ) ;  COPY SNIPPET The setDefaultNav...