Set Up ExpressJS Session Authentication for Node Applications
When creating an application that authenticates users, you have two main choices for authorization and storing user data:
- Sessions
- JSON Web Tokens (JWT)
Sessions are the traditional method and used by many applications. It is a straightforward and secure way to manage the user data your application needs for page loads. The express-session project is a handy library for adding session handling into your ExpressJS applications. It is the standard used by most organizations today.
In this tutorial we’ll:
- Learn how to install and setup express-session
- Generate and assign random session IDs
- Configure session cookies in our Node application
- Add express-session to an existing ExpressJS form
By the end of this tutorial, you should have a firm understanding of how to use express-session to allow users to log in to a Node.js application.
This tutorial is part 6 of 7 tutorials that walk through using Express.js for user authentication.
Goal
Learn the fundamentals of incorporating express-session into your application.
Prerequisites
- What Is the Difference Between Sessions and JSON Web Tokens Authentication?
- How to Make a Login Form with ExpressJS
Storing session data
The most popular choices for storing session data are:
- Redis
- NoSQL Database (i.e. MongoDB)
- SQL Database (i.e. MySQL)
Each session gets assigned a unique ID, and that session ID gets stored in a session cookie. The session ID is used to query additional user data safely stored in the database.
To focus on the session code, external storage is not covered or used in this tutorial. In production you want to be sure to choose secure external storage for your application.
Install dependencies
Before we work on the code, we will install the necessary dependencies.
If you do not already have ExpressJS installed, install it now.
npm install express
Next, install express-session.
npm install express-session
To randomly generate session IDs, we are going to use a library called UUID. Let’s install it now.
npm install uuid
Set up express-session with a randomly generated session ID
Next, we will work on the code to set up express-session with a randomly generated session ID. Random session IDs add security to your application. Without this security feature, hackers can easily use software to guess existing session IDs and infiltrate data.
In this example, I am not including code to check for uniqueness. Real-life applications need to include this step as no 2 users should have the same session ID — the same as you would check for uniqueness with usernames and user IDs. If you are storing session data in a database, it can be done by querying the database to check if the ID exists.
Include dependencies
At the top of our file, we will include our installed libraries:
- ExpressJS
- express-session
- UUID
const express = require('express'); // ExpressJSconst session = require('express-session'); // express-sessionsconst { v4: uuidv4 } = require('uuid'); // uuid, To call: uuidv4();
Create an ExpressJS application
Next, we will create our ExpressJS application.
// Create an Express Appconst app = express();
Configure sessions
Now we are ready to configure the express-session middleware. We will start by having our application use the middleware.
// Configure Sessions Middlewareapp.use(session({ }));
When we set our application to use express-session, we can also specify configuration options. Here are the options we set in this example:
genid
: This option creates a session ID by using a function ofreq
. We are using the UUID library to call the functionuuidv4()
and set a random ID.secret
: This required option can be set to a string or an array of strings. In our example, we will use a single string. The secret signs the cookie that stores the session ID. It should be a random string that is difficult for a hacker to guess. I used RandomKeygen to generate a string. The secret should be constant. If it changes, existing sessions become invalid. In a real life application the secret should be loaded from an environmental variable, and not in the source code.resave
: Resave is eithertrue
orfalse
. Iftrue
, whether or not the data has changed, the session data is forcibly saved. Most of the time, you want this set tofalse
to reduce calls to your database.saveUninitialized
: This is alsotrue
orfalse
. Iftrue
, new uninitialized sessions get forcibly saved.
To set these options, we will write the following code:
// Configure Sessions Middlewareapp.use(session({ genid: function (req) { return uuidv4(); }, secret: '=fmLV*U@FL`N]]~/zqtFCch.pBTGoU', resave: false, saveUninitialized: true}));
Add a GET route
Next, we make our home page’s GET route. The code responds by displaying the session ID in the web browser when a user navigates to the application. To access the session ID, we reference req.sessionID
.
// Home Page Routeapp.get('/', (req, res) => { res.send(req.sessionID);});
Set the server port
Finally, we are ready to set which port our application listens on.
const port = 9000 // Port we will listen on
// Function to listen on the portapp.listen(port, () => console.log(`This app is listening on port ${port}`));
Run the application
Your final code should look like this:
const express = require('express'); // ExpressJSconst session = require('express-session'); // express-sessionsconst { v4: uuidv4 } = require('uuid'); //To call: uuidv4();
// Create an Express Appconst app = express();
// Configure Sessions Middlewareapp.use(session({ genid: function (req) { return uuidv4(); }, secret: '=fmLV*U@FL`N]]~/zqtFCch.pBTGoU', resave: false, saveUninitialized: true,}));
// Home Page Routeapp.get('/', (req, res) => { res.send(req.sessionID);})
const port = 9000 // Port we will listen on
// Function to listen on the portapp.listen(port, () => console.log(`This app is listening on port ${port}`));
I have it saved in a file called server.js.
Start your Express server, by running the code in your terminal.
node server.js
Then navigate to http://localhost:9000/ to test the code. You should see a session ID displayed on the page.
Configure Cookies
There might be specifications you want to set for session cookies. Many of these specifications are set via the cookie option.
cookie.maxAge
maxAge
allows you to specify how long (in milliseconds) the cookie is allowed to live, thus dictating its expiration date. Let’s set the maxAge
to one hour.
cookie: { maxAge: 60 * 60 * 1000 }, // 1 hour
Added to our example session configuration:
// Configure Sessions Middlewareapp.use(session({ genid: function (req) { return uuidv4(); }, secret: '=fmLV*U@FL`N]]~/zqtFCch.pBTGoU', resave: false, saveUninitialized: true, cookie: { maxAge: 60 * 60 * 1000 } // 1 hour}));
Another way to set options is via req.session
. Many session options can be set in the same manner.
req.session.cookie.maxAge = 60 * 60 * 1000;
cookie.secure
This option is either true or false. When true, cookies will only be set over a secure https-enabled website. Cookies are not secure over http. By default it is set to false, but true is recommended.
// Configure Sessions Middlewareapp.use(session({ genid: function (req) { return uuidv4(); }, secret: '=fmLV*U@FL`N]]~/zqtFCch.pBTGoU', resave: false, saveUninitialized: true, cookie: { maxAge: 60 * 60 * 1000, secure: true }}));
If you are using a proxy you will need to include ‘trust proxy’ prior to configuring cookies.
app.set('trust proxy', 1)
For more information and a full list of options, please visit the express-session documentation.
Add express-session to existing code
In a previous tutorial, How to Make a Login Form with ExpressJS, we created an ExpressJS form. We are going to add express-session to the code by making the following modifications to server.js:
Include express-session and uuid:
const session = require('express-session'); // express-sessionsconst { v4: uuidv4 } = require('uuid'); //To call: uuidv4
Add and configure express-sessions middleware:
app.use(session({ genid: function (req) { return uuidv4(); }, secret: 'r8q,+&1LM3)CD*zAGpx1xm{NeQhc;#', resave: false, saveUninitialized: true, cookie: { maxAge: 60 * 60 * 1000 } // 1 hour}));
Modify the application’s response to /login post requests:
- User data can be stored as a property of
req.session
. To demonstrate this we store the username (req.body.username
) inreq.session.username
. - We then respond with a message containing the username, session ID, and maxAge of the cookie.
// login post routeapp.post('/login', (req, res) => { req.session.username = req.body.username; res.send(`Hello ${req.session.username}. Your session ID is ${req.sessionID} and your session expires in ${req.session.cookie.maxAge} milliseconds.`);});
Your server.js should now look like this:
const express = require('express'); // Include ExpressJSconst app = express(); // Create an ExpressJS appconst bodyParser = require('body-parser'); // Middlewareconst session = require('express-session'); // express-sessionsconst { v4: uuidv4 } = require('uuid'); //To call: uuidv4
app.use(bodyParser.urlencoded({ extended: false }));
// Configure Sessions Middlewareapp.use(session({ genid: function (req) { return uuidv4(); }, secret: 'r8q,+&1LM3)CD*zAGpx1xm{NeQhc;#', resave: false, saveUninitialized: true, cookie: { maxAge: 60 * 60 * 1000 } // 1 hour}));
// Route to Homepageapp.get('/', (req, res) => { res.sendFile(__dirname + '/static/index.html');});
// Route to Login Pageapp.get('/login', (req, res) => { res.sendFile(__dirname + '/static/login.html');});
// /login post routeapp.post('/login', (req, res) => { req.session.username = req.body.username; res.send(`Hello ${req.session.username}. Your session ID is ${req.sessionID} and your session expires in ${req.session.cookie.maxAge} milliseconds.`);});
const port = 3000 // Port we will listen on
// Function to listen on the portapp.listen(port, () => console.log(`This app is listening on port ${port}`));
When you navigate to http://localhost:3000/login (HTML code included in original tutorial) you should see this:
When you submit the form you should now see the username, sessionID, and maxAge displayed in your browser.
Recap
Sessions are a straightforward method of storing user data. This data may be used to authorize or personalize page loads. The express-session library makes it simple to incorporate this technique into your Express code.
Session data is usually stored on the server, possibly in a secure database. To access this data we reference a session ID. Session IDs should be random and secure to protect against security threats. In this tutorial we used uuid to generate random IDs.
Keep going with the next tutorial in this set: Authenticate Users With Node ExpressJS and Passport.js.
Further your understanding
- What session storage do you prefer?
- Would you save session data in a JSON file?
- What user data would a banking application need to display a user’s account summary?
Additional resources
- Express Session Documentation (expressjs.com)
- Express Session on npm (npmjs.com)
- Express Middleware in NodeJS (HeyNode.com)