How does session management work in Express.js?
Session Management in Express.js
Sessions allow you to persist data across multiple HTTP requests from the same client. Since HTTP is stateless, sessions provide state by storing data on the server and identifying the client with a cookie.
How Sessions Work
Client Server
β β
βββ GET /login ββββββββββ>β
β β Creates session, stores in memory/DB
β<ββ Set-Cookie: sid=abcβββ
β β
βββ GET /dashboard ββββββ>β Cookie: sid=abc
β β Looks up session by "abc"
β<ββ User dashboard ββββββUsing express-session
bash
npm install express-sessionjs
const session = require('express-session');
app.use(session({
secret: process.env.SESSION_SECRET,
resave: false,
saveUninitialized: false,
cookie: {
secure: process.env.NODE_ENV === 'production', // HTTPS only
httpOnly: true, // Not accessible via JavaScript
maxAge: 24 * 60 * 60 * 1000, // 24 hours
sameSite: 'lax' // CSRF protection
}
}));Using Sessions
js
// Login β store user in session
app.post('/login', async (req, res) => {
const user = await authenticate(req.body);
if (user) {
req.session.userId = user.id;
req.session.role = user.role;
res.json({ message: 'Logged in' });
} else {
res.status(401).json({ error: 'Invalid credentials' });
}
});
// Protected route β check session
app.get('/dashboard', (req, res) => {
if (!req.session.userId) {
return res.status(401).json({ error: 'Not authenticated' });
}
res.json({ message: `Welcome, user ${req.session.userId}` });
});
// Logout β destroy session
app.post('/logout', (req, res) => {
req.session.destroy((err) => {
if (err) return res.status(500).json({ error: 'Logout failed' });
res.clearCookie('connect.sid');
res.json({ message: 'Logged out' });
});
});Session Stores
By default, sessions are stored in memory (not suitable for production):
| Store | Package | Best For |
|---|---|---|
| Memory | Built-in | Development only |
| Redis | connect-redis | Production (fast, scalable) |
| PostgreSQL | connect-pg-simple | When you already use Postgres |
| MongoDB | connect-mongo | When you already use MongoDB |
js
const RedisStore = require('connect-redis').default;
const { createClient } = require('redis');
const redisClient = createClient({ url: process.env.REDIS_URL });
await redisClient.connect();
app.use(session({
store: new RedisStore({ client: redisClient }),
secret: process.env.SESSION_SECRET,
resave: false,
saveUninitialized: false
}));Sessions vs JWT
| Feature | Sessions | JWT |
|---|---|---|
| Storage | Server-side | Client-side (token) |
| Scalability | Needs shared store | Stateless |
| Revocation | Easy (delete session) | Hard (blacklist needed) |
| Size | Small cookie | Larger token |
| Security | Cookie attributes | Token validation |
| Best for | Traditional web apps | APIs, SPAs, microservices |
Recommendation: Use sessions for server-rendered apps. Use JWT for APIs consumed by SPAs or mobile apps. For large-scale systems, use Redis-backed sessions for easy horizontal scaling.
Short Answer
Interview readyPremium
A concise answer to help you respond confidently on this topic during an interview.