ExpressJS - Sessions
Modern Guide to Express.js Sessions
Section titled “Modern Guide to Express.js 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-sessionIn 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.
Example: A Simple Page View Counter
Section titled “Example: A Simple Page View Counter”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.
index.js
Section titled “index.js”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}`);});Explanation
Section titled “Explanation”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.envfile).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.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.cookie.secure: true: In production, this should betrue. It ensures the browser only sends the cookie over HTTPS.req.session: The middleware adds asessionobject 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.