Cookie Session Middleware
cookie-session is a lightweight middleware for Node.js, primarily used with Express, that implements client-side session management. Unlike server-side session stores (like `express-session`), this module stores the entire session data directly within a signed, but unencrypted, cookie on the client's browser. This approach means no server-side database or resources are required for session storage, which can simplify deployments, especially in load-balanced environments. The current stable version is 2.1.1, released in April 2024, indicating active maintenance. Releases typically align with updates to its underlying `cookies` and `keygrip` dependencies, or to address compatibility with newer Node.js versions. Key differentiators include its minimal server-side footprint and the direct storage of session data in the client's cookie, making it suitable for 'light' sessions or as a complement to a secondary, database-backed store for larger data payloads.
Common errors
-
TypeError: req.session.save is not a function
cause The `req.session.save()` method was removed in `cookie-session` v2.0.0 as session changes are now automatically saved upon response end.fixRemove all explicit calls to `req.session.save()`. The middleware automatically handles saving changes to `req.session`. -
Error: 'keys' must be provided to sign the cookie.
cause The `keys` option (or `secret` for a single key) is mandatory for `cookie-session` to sign the session cookie, which prevents tampering. Without it, the middleware cannot function securely.fixProvide an array of strong secret strings to the `keys` option in the middleware configuration, e.g., `app.use(cookieSession({ name: 'session', keys: ['secret1', 'secret2'] }))`. In production, these should be loaded from environment variables. -
No 'Set-Cookie' header is sent, and no session cookie is created.
cause The `cookie-session` middleware only sets a session cookie if `req.session` contains any data (i.e., it's not an empty object).fixEnsure you add at least one property to `req.session` (e.g., `req.session.initialized = true;`) at some point during the request if you want a session cookie to be created for the user. -
ReferenceError: require is not defined (in an ES Module context)
cause Attempting to use CommonJS `require()` syntax in a JavaScript file that is treated as an ES Module (e.g., `"type": "module"` in `package.json` or `.mjs` file extension).fixUse the ES Module import syntax: `import cookieSession from 'cookie-session';`. Ensure your environment supports ES Modules.
Warnings
- breaking In version 2.0.0, the default cookie name was changed from an implicitly derived or internal 'key' to 'session'. The 'key' option was explicitly removed and developers must now use the 'name' option to specify the cookie name.
- breaking Version 2.0.0 deprecated and removed several properties and methods from `req.session`, including `req.session.save()`, `req.session.length`, `.populated` (replaced by `.isPopulated`), `req.sessionCookies`, and `req.sessionKey`. Attempting to use these will result in errors.
- gotcha This module *only signs* the session cookie to prevent tampering; it *does not encrypt* the session data. The client can read the entire contents of `req.session` by inspecting the cookie value. Do not store sensitive, unencrypted data in `req.session`.
- gotcha The module does not inherently prevent session replay attacks. The expiration time set on the cookie only controls when the browser discards it. A client can save and re-use an unexpired cookie. Additionally, a session cookie will only be sent if `req.session` contains *any* data. An empty `req.session` will not trigger a `Set-Cookie` header.
Install
-
npm install cookie-session -
yarn add cookie-session -
pnpm add cookie-session
Imports
- cookieSession
const cookieSession = require('cookie-session')import cookieSession from 'cookie-session'
- cookieSession
import { cookieSession } from 'cookie-session'const cookieSession = require('cookie-session')
Quickstart
import express from 'express';
import cookieSession from 'cookie-session';
const app = express();
// Ensure you provide at least one strong secret key.
// In production, these should be loaded from environment variables.
const SESSION_SECRET_KEYS = process.env.SESSION_SECRET_KEYS ?
process.env.SESSION_SECRET_KEYS.split(',') : ['supersecretkey1', 'anothersupersecretkey2'];
app.use(cookieSession({
name: 'session',
keys: SESSION_SECRET_KEYS,
maxAge: 24 * 60 * 60 * 1000, // 24 hours
httpOnly: true, // Recommended for security
secure: process.env.NODE_ENV === 'production', // Use secure cookies in production
sameSite: 'lax' // Recommended for security
}));
app.get('/', (req, res) => {
// Access and modify session data via req.session
req.session.views = (req.session.views || 0) + 1;
res.send(`Hello! You've viewed this page ${req.session.views} times. Session ID: ${req.session.id || 'N/A'}`);
});
app.get('/login', (req, res) => {
req.session.user = { id: 1, name: 'John Doe' };
req.session.loggedInAt = Date.now();
res.redirect('/');
});
app.get('/logout', (req, res) => {
req.session = null; // Clears the session cookie
res.redirect('/');
});
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
console.log(`Server running on http://localhost:${PORT}`);
console.log('Try visiting / and then /login and /logout');
});