How to implement session with express-session?

856 Views Asked by At

I’m considering using session in my node.js application.

I understand the following: - session-cookie use cookie to save session data on the client side - express-session use cookie to store a sessionID and all the session data are stored on the server side

I’m worried about security so I would choose express-session. But the Documentation say that by default express-session store data in memory and this not envisageable in production.

So my questions are: How do you implement session in your application? Do session stores are not influencing performance? If not, which session store would you recommend me? (my application is using MySql as database)

Thank you very much for your help. Regards.

1

There are 1 best solutions below

2
Cacoon On

The easiest way I found to manage session data is tokens.

You can easily use 'passport' for expressjs and nodejs.

You can generate a token that is signed in your NodeJS backend with a private key and identifiable by the public key. These tokens can even be revoked.

They are passed into the 'authorization' header as a web standard.

Here is an example of validation I use for extracting and checking a generated token a user has provided.

module.exports.ensureAuthorized = function ensureAuthorized(req, res) {
    return new Promise((resolve) => {
        let bearerToken;
        let bearerHeader = req.headers["authorization"];
        if (typeof bearerHeader !== 'undefined') {
            let bearer = bearerHeader.split(" ");
            bearerToken = bearer[1];
            req.token = bearerToken;
            this.userPayload(req.token).then((result) => {
                if (!result) {
                    return res.status(403).json({message:"Failed to verify token supplied in authorization header", data: null});
                }else{
                    resolve(result);
                }
            });
        } else {
            return res.status(403).json({message:"Failed to supply token in authorization header.", data: null});
        }
    });
};

And here is my REST API call for a user attempting to login: (that generates a valid token)

let jwt = require('jsonwebtoken');
let config = require('../../misc/config');
global.atob = require("atob");
let mongoose = require('mongoose');

exports.getLogin = function(req, res) {
    const btoaAuth = (req.headers.authorization || '').split(' ')[1] || '';
    const [username, password, rememberMe] = atob(btoaAuth).toString().split(':');
    if(username && password) {
        usersModel.findOneAndUpdate({username: username},{lastLogin: new Date(),})
            .exec(function (err, userResult) {
                if(err) return res.status(500).json({message: "Server failed search users", data: err});
                if(!userResult) return res.status(500).json({message: "Username invalid", data: err});
                userResult.verifyPassword(password, function(err, isMatch) {
                    if (err) {  return res.status(500).json({message: "Server failed to process user login", data: err});}

                    // Password did not match
                    if (!isMatch) {  return res.status(403).json({message: "Password incorrect", data: err}); }
                    // Success
                    let token = jwt.sign({_id: userResult._id,username: userResult.username, exp: rememberMe === 'true'? Math.floor(Date.now() / 1000) + (60 * 60 * 24 * 365 * 100) : Math.floor(Date.now() / 1000) + (60 * 60) }, config.jwtSecret);
                    let obj = {};
                    obj['profile'] = userResult;
                    obj['profile']['password'] = undefined;
                    obj['token'] = token;
                    return res.status(200).json({message: "Successful login", data: obj});
                });
            });
    }else{
        return res.status(400).json({message: "Username and password are required", data: req.body});
    }
};