ExpressJS - Cookies
Express.js - Managing Cookies
Section titled “Express.js - Managing Cookies”HTTP cookies are small pieces of data that a server sends to the user’s web browser. The browser stores them and sends them back with every subsequent request to the same server. Cookies are essential for features like session management (tracking logins), personalization (user preferences), and user tracking.
To work with cookies in Express, you need the cookie-parser middleware. It parses the Cookie header on incoming requests and populates req.cookies with an object keyed by the cookie names. It also adds a res.cookie() method to set cookies.
Setup and Basic Usage
Section titled “Setup and Basic Usage”First, install cookie-parser as a dependency:
npm install cookie-parserNext, import and apply it as middleware in your index.js. It’s important to place it before any routes that need to access cookies.
import express from 'express';import cookieParser from 'cookie-parser';
const app = express();
// Apply the cookie-parser middleware// We'll add a secret later for signed cookiesapp.use(cookieParser());
// ... your routesSetting and Reading a Cookie
Section titled “Setting and Reading a Cookie”Let’s create two routes: one to set a cookie and another to read it.
index.js
Section titled “index.js”// Route to set a cookieapp.get('/set-cookie', (req, res) => { // Sets a cookie named 'userTheme' with the value 'dark' res.cookie('userTheme', 'dark'); res.send('Cookie has been set! Check your browser dev tools.');});
// Route to read the cookieapp.get('/get-cookie', (req, res) => { // Access the cookies from the request object const theme = req.cookies.userTheme; if (theme) { res.send(`Your theme is set to: ${theme}`); } else { res.send('No theme cookie found.'); }});
// ... app.listenAfter running your server, first visit http://localhost:3000/set-cookie. Then, visit http://localhost:3000/get-cookie. You should see the message confirming your theme. You can also inspect the stored cookies in your browser’s developer tools (usually in the Application or Storage tab).
Secure Cookie Best Practices
Section titled “Secure Cookie Best Practices”Simply setting a cookie is often not enough for production applications. You must configure them securely to prevent common attacks like Cross-Site Scripting (XSS) and Cross-Site Request Forgery (CSRF).
The res.cookie() method accepts an options object as its third argument. Here are the most important security options:
httpOnly: true: This is critical. It prevents the cookie from being accessed by client-side JavaScript (document.cookie). This mitigates XSS attacks where an attacker tries to steal cookies.secure: true: Ensures the cookie is only sent over HTTPS connections. You should always enable this in production.sameSite: 'strict'or'lax': A powerful defense against CSRF attacks.'strict'prevents the browser from sending the cookie on any cross-site requests.'lax'is a reasonable default that allows cookies to be sent on top-level navigation (e.g., clicking a link from another site).maxAgeorexpires: Sets the cookie’s expiration.maxAgeis a time in milliseconds from now, whileexpiresis a specificDateobject.
Example: Setting a Secure Cookie
Section titled “Example: Setting a Secure Cookie”app.get('/set-secure-cookie', (req, res) => { const options = { maxAge: 7 * 24 * 60 * 60 * 1000, // 7 days in milliseconds httpOnly: true, // The cookie only accessible by the web server secure: process.env.NODE_ENV === 'production', // Only set on HTTPS sameSite: 'lax' // Or 'strict' };
res.cookie('sessionToken', 'abc123xyz', options); res.send('Secure cookie set!');});Signed Cookies
Section titled “Signed Cookies”Cookies are stored on the client and can be tampered with. To ensure a cookie’s value hasn’t been changed, you can use signed cookies. cookie-parser can do this if you provide it with a secret string.
Important: Your secret should be a long, random string stored securely as an environment variable, not hardcoded.
index.js (Updated Setup)
Section titled “index.js (Updated Setup)”// Secret should come from an environment variable for securityconst COOKIE_SECRET = process.env.COOKIE_SECRET || 'default-secret';
app.use(cookieParser(COOKIE_SECRET));Setting and Reading a Signed Cookie
Section titled “Setting and Reading a Signed Cookie”// Setting a signed cookieapp.get('/set-signed-cookie', (req, res) => { res.cookie('userRole', 'admin', { signed: true }); res.send('Signed cookie has been set.');});
// Reading a signed cookieapp.get('/get-signed-cookie', (req, res) => { // Unsigned cookies are in req.cookies // Signed cookies are in req.signedCookies const userRole = req.signedCookies.userRole;
if (userRole) { res.send(`Your role is: ${userRole}`); } else { // This will be the case if the cookie is tampered with or not set res.status(401).send('Invalid or missing role cookie.'); }});Deleting a Cookie
Section titled “Deleting a Cookie”To delete a cookie, use res.clearCookie(). You must pass the same options (like domain and path) that you used when setting it.
app.get('/logout', (req, res) => { res.clearCookie('sessionToken'); res.send('You have been logged out.');});