The session is a mechanism to maintain state information about a user’s interactions with a website or web application. It persists data across multiple requests from the same client.
You can create proper authentication or manage shopping cart information using a session.
Implementing session management in Node.js applications
Express is a web server built on the Node.js platform. We will use the express web framework for session management.
To implement proper session management in Node.js Express web server, use express-session middleware.
The express-session middleware is used to manage user sessions.
Here is the step-by-step guide to creating and destroying sessions in Node.js:
Step 1: Install the necessary libraries
To continue with our small application, You must have Node.js installed on your machine. If not, please install It first.
Create a project folder called new-app and go inside the folder:
mkdir new-app cd new-app
We need the express, express-session, and dotenv libraries. Optionally, you can install the Morgan library to log the requests.
npm install express express-session dotenv morgan
We will use the ES modules to import, so add type:module inside the package.json file like this:
Here is the package.json file:
{ "type": "module", "dependencies": { "dotenv": "^16.4.5", "express": "^4.19.2", "express-session": "^1.18.0", "morgan": "^1.10.0" } }
Step 2: Create a .env file
Inside the root of your directory, create a new file called .env and define the environment variables in it:
PORT=4000 SESSION_SECRET=your_secret NODE_ENV=development
We defined three env variables that we will use in our express web application.
Replace your_secret with an actual secret key, which can be anything you want. These variables are server-related configurations or confidential keys.
Make sure to add this .env file to the .gitignore file to prevent it from being exposed publicly.
Step 3: Create an app.js file
Now is the time to create an actual application file called “app.js” inside the root of your project and import these newly installed libraries like this:
import express from 'express'; import session from 'express-session'; import { config } from 'dotenv'; import morgan from 'morgan';
You can see that we used the ES module syntax.
Step 4: Loading environment variables
We imported the config() function from the dotenv package to load environment variables from a .env file into process.env. In short, the config() function allows us to use environment variables defined in the .env file.
Append the below code inside the “app.js” file.
// Load environment variables from .env file config();
Step 5: Create an instance of an express web application
To create an instance of express, use the express() function.
This instance can then be used to define routes or middlewares.
We will define two express middlewares:
- morgan: It logs every http request in the “dev” format.
- json: It uses built-in express middleware to parse incoming JSON requests.
Also, define the port for our application using the process.env property.
Append the below code inside the “app.js” file:
// Create an instance of the Express application const app = express(); // Define the port number const PORT = process.env.PORT; // Middleware app.use(morgan('dev')); app.use(express.json());
Step 6: Configure the session middleware
To configure session middleware, use the app.use(session({})) function.
// Configure the Session Middleware app.use(session({ secret: process.env.SESSION_SECRET, // Replace with your secret key resave: false, // Forces the session to be saved back to the store saveUninitialized: false, // Forces a session that is "uninitialized" to be saved to the store cookie: { secure: process.env.NODE_ENV === 'production' } // Set to true if using HTTPS }));
The session() function accepts a JavaScript Object that contains the following properties:
- secret: We already defined that secret inside the .env file. We just referred to that here.
- resave: If set to false, it prevents the session from being saved back to the session store if it was never modified during the request.
- saveUninitialized: If set to false, it prevents uninitialized sessions from being saved to the store.
- cookie: It sets the secure flag on the session cookie.
Step 7: Defines a route handler for GET
Use the app.get() function to handle the GET request in Express.
Use the req.sessions.views property to check if a session is set.
The session will initiate for the first time in our application when the User sends the first GET request.
Here’s how you define route handler to demonstrate the sessions. Add the following code to the “app.js” file:
// Route to Demonstrate Sessions app.get('/', (req, res) => { if (req.session.views) { req.session.views++; res.send(`Number of views: ${req.session.views}`); } else { req.session.views = 1; res.send('Welcome to the session demo. Refresh!'); } }); // Start the Express server app.listen(PORT, () => { console.log(`Server is running on port ${PORT}`); });
When the User sends the GET request to http://localhost:4000/ URL, it will check for the req.sessions.views property.
If the views property exists on the session object, it increments the view count, and if it does not, it initializes it to 1 and sends a welcome message.
We also wrote a code that starts an express web server using the app.listen() function.
To test our endpoint, open the POSTMAN, construct a GET request, and see the response:
Here is the screenshot of the first GET request in POSTMAN:
Now that we have initialized a session variable views, we can increment that counter by sending consequent requests. If you send a request a second or third time, the views counter will be incremented by one.
Each time you send a request, it will be incremented by 1.
Here is the second screenshot:
Since we are logging each request through Morgan, we can see all the requests like this:
Step 8: Destroying the session
To destroy a session, use the req.session.destroy() function in Node.js.
We need to define a POST route that destroys the session.
Add the below code in the “app.js” file:
// Route to destroy the session app.post('/logout', (req, res) => { req.session.destroy(err => { if (err) { return res.status(500).send('Failed to log out.'); } res.clearCookie('connect.sid'); // Adjust the cookie name if necessary res.send('Logged out successfully.'); }); });
In this code, we used the req.session.destroy() function to clear the cookie and send the message to the client that “Logged out successfully” means the session has been destroyed.
The res.clearCookie(‘connect.sid’) function clears the session cookie from the client. The cookie name connect.sid is the default name used by express-session.
Here is the complete code for the app.js file:
import express from 'express'; import session from 'express-session'; import { config } from 'dotenv'; import morgan from 'morgan'; // Load environment variables from .env file config(); // Create an instance of the Express application const app = express(); // Define the port number const PORT = process.env.PORT; // Middleware app.use(morgan('dev')); app.use(express.json()); // Configure the Session Middleware app.use(session({ secret: process.env.SESSION_SECRET, // Replace with your secret key resave: false, // Forces the session to be saved back to the store saveUninitialized: false, // Forces a session that is "uninitialized" to be saved to the store cookie: { secure: process.env.NODE_ENV === 'production' } // Set to true if using HTTPS })); // Route to Demonstrate Sessions app.get('/', (req, res) => { if (req.session.views) { req.session.views++; res.send(`Number of views: ${req.session.views}`); } else { req.session.views = 1; res.send('Welcome to the session demo. Refresh!'); } }); // Route to destroy the session app.post('/logout', (req, res) => { req.session.destroy(err => { if (err) { return res.status(500).send('Failed to log out.'); } res.clearCookie('connect.sid'); // Adjust the cookie name if necessary res.send('Logged out successfully.'); }); }); // Start the Express server app.listen(PORT, () => { console.log(`Server is running on port ${PORT}`); });
Save this file, go to the POSTMAN, and construct the POST request like this:
You can see that we get the message that ultimately says, “Session has been destroyed!”
If you send the GET request again, the views counter will get initialized with value 1 because a new session will be established.
The same mechanism is used when logging in to the application and storing the session ID in the cookie. When you log out, the session ID will be destroyed.
Destroying sessions and clearing cookies helps to manage session data more effectively and prevents old sessions from lingering and causing unexpected behavior.
Conclusion
Session management is a key part of any web application, and securely deploying it is not easy. But we have done it in Node.js with the help of different libraries and secure coding.
In this article, we saw what a session is and what libraries are required to implement it. Then, we defined a route to create and destroy that session. Test the API endpoints using POSTMAN.
Tula
I got this error when I run this example and go to http://localhost:3000/user.
“Error: ENOENT: no such file or directory, lstat ‘C:\Users\cuyi\Desktop\node\expresses-session-example\views\partials’ “
Krunal
Please make a directory inside views folder called partials.
Cesar Gnanago
Good evening and thank you for doing this tutorial. An error occurs making a request to the page http://localhost:3000/user :
Cannot read property ‘errors’ of undefined
Ayesha Bhatnagar
Thank-you! This is very helpful. You should publish more. 5/5 !!!