Skip to content

ExpressJS - Sessions

HTTP is inherently stateless. To maintain user-specific data across multiple requests (like a shopping cart or login status), we use sessions. A session works by giving the client a unique ID (usually in a cookie). The client sends this ID with each request, and the server uses it to retrieve the stored session data. This keeps sensitive session data on the server, not the client.

We’ll use the standard express-session middleware to manage sessions.

# Install the session middleware
$ npm install express-session

In the example below, we’ll configure the express-session middleware. For development, the default MemoryStore is fine, but it’s not suitable for production because it leaks memory and doesn’t scale beyond a single process. For production, always use a persistent session store like connect-redis or connect-mongo.

This application demonstrates a basic session. When a user first visits, we initialize a page_views property on their session. On subsequent visits from the same user, we increment the counter.

import express from 'express';
import session from 'express-session';
import 'dotenv/config'; // For loading environment variables
const app = express();
const PORT = 3000;
// **Security Best Practice**: The session secret should be a random, long string
// stored in an environment variable, not hardcoded.
if (!process.env.SESSION_SECRET) {
console.error('FATAL ERROR: SESSION_SECRET is not defined.');
process.exit(1);
}
app.use(session({
secret: process.env.SESSION_SECRET,
resave: false, // Don't save session if unmodified
saveUninitialized: false, // Don't create session until something stored
cookie: {
secure: process.env.NODE_ENV === 'production', // Use secure cookies in production
httpOnly: true, // Prevents client-side JS from reading the cookie
maxAge: 1000 * 60 * 60 // Cookie expiry time in milliseconds (e.g., 1 hour)
}
}));
app.get('/', (req, res) => {
if (req.session.page_views) {
req.session.page_views++;
res.send(`You have visited this page ${req.session.page_views} times.`);
} else {
req.session.page_views = 1;
res.send('Welcome! This is your first visit.');
}
});
app.listen(PORT, () => {
console.log(`Server running on http://localhost:${PORT}`);
});
  1. secret: This is used to sign the session ID cookie. It should be a long, random string stored securely in an environment variable (e.g., in a .env file).
  2. resave: false: This is a recommended setting. It prevents the session from being saved back to the session store if it wasn’t modified during the request.
  3. saveUninitialized: false: Another recommended setting. It prevents a session from being created for a user until something is actually stored in it, which saves storage space and complies with some privacy regulations.
  4. cookie.secure: true: In production, this should be true. It ensures the browser only sends the cookie over HTTPS.
  5. req.session: The middleware adds a session object to the request (req). You can attach any serializable data to it. Changes are automatically saved at the end of the request.

After running the app and visiting http://localhost:3000, you will see the welcome message. Refreshing the page will increment the view count, demonstrating that the session is persisting across requests.