Express Cheatsheet
Cookies and Sessions
Use this Express reference while you build software engineering projects, review code for technical interview prep, or polish examples for a software engineer resume.
Sessions
Sessions store state server-side; only a session ID is in the cookie.
express-session
npm install express-session
const session = require('express-session'); app.use(session({ secret: process.env.SESSION_SECRET, // used to sign the session ID cookie resave: false, // don't save session if unmodified saveUninitialized: false, // don't create session for unauthenticated requests name: 'sid', // cookie name (default: 'connect.sid') cookie: { httpOnly: true, secure: process.env.NODE_ENV === 'production', sameSite: 'lax', maxAge: 24 * 60 * 60 * 1000, // 1 day }, }));
Using the Session
// Write to session app.post('/login', (req, res) => { // validate credentials ... req.session.userId = user.id; req.session.role = user.role; res.json({ ok: true }); }); // Read from session app.get('/profile', (req, res) => { if (!req.session.userId) return res.status(401).json({ error: 'Not logged in' }); res.json({ userId: req.session.userId }); }); // Destroy session on logout app.post('/logout', (req, res, next) => { req.session.destroy((err) => { if (err) return next(err); res.clearCookie('sid'); res.json({ ok: true }); }); }); // Regenerate session ID (prevent session fixation after login) app.post('/login', async (req, res, next) => { // ...validate... req.session.regenerate((err) => { if (err) return next(err); req.session.userId = user.id; res.json({ ok: true }); }); });
Session Methods and Properties
| Member | Description |
|---|---|
req.session | Session data object (add any properties) |
req.session.id | Session ID (same as req.sessionID) |
req.sessionID | Session ID string |
req.session.cookie | Cookie options for this session |
req.session.save(cb) | Force save to store |
req.session.reload(cb) | Reload from store |
req.session.destroy(cb) | Destroy session + remove from store |
req.session.regenerate(cb) | Create new session ID (same data) |
req.session.touch() | Reset expiry |
Session Stores
The default in-memory store leaks memory and loses data on restart. Use a persistent store in production.
// connect-pg-simple (PostgreSQL) const pgSession = require('connect-pg-simple')(session); app.use(session({ store: new pgSession({ pool: pgPool, tableName: 'user_sessions' }), // ... })); // connect-redis (v8+, 2024 — named export; v7 was require('connect-redis').default) const { RedisStore } = require('connect-redis'); const { createClient } = require('redis'); const client = createClient({ url: process.env.REDIS_URL }); await client.connect(); app.use(session({ store: new RedisStore({ client }), // ... })); // connect-mongo const MongoStore = require('connect-mongo'); app.use(session({ store: MongoStore.create({ mongoUrl: process.env.MONGO_URL }), // ... }));
Flash Messages
Short-lived messages (e.g., "Login failed") stored in the session for one request.
npm install connect-flash
const flash = require('connect-flash'); app.use(flash()); // Set a flash message app.post('/login', (req, res) => { req.flash('error', 'Invalid credentials'); res.redirect('/login'); }); // Read flash messages (consumed on read — gone after) app.get('/login', (req, res) => { res.render('login', { errors: req.flash('error') }); });
CSRF Protection
For form-based apps that use cookies, protect against CSRF. The historical csurf package is deprecated and unmaintained — implement the synchronizer-token or double-submit-cookie pattern yourself (or use a maintained package like csrf-csrf).
// Synchronizer token pattern (with express-session) app.use((req, res, next) => { if (!req.session.csrfToken) { req.session.csrfToken = require('crypto').randomBytes(32).toString('hex'); } res.locals.csrfToken = req.session.csrfToken; next(); }); app.use((req, res, next) => { if (['GET', 'HEAD', 'OPTIONS'].includes(req.method)) return next(); const token = req.body._csrf || req.headers['x-csrf-token']; if (token !== req.session.csrfToken) { return res.status(403).json({ error: 'Invalid CSRF token' }); } next(); });
With
sameSite: 'strict'or'lax'cookies, most CSRF attacks are already blocked without a token — but a token provides defense in depth.