Read and Set Cookies — Securely
Cookies
Cookies arrive in the Cookie header, are set with Set-Cookie. Get the attributes right.
What you'll learn
- Parse a Cookie header
- Set a cookie with the right attributes
- Know HttpOnly, Secure, SameSite
Cookies are small key-value pairs the browser sends on every request to your domain. Sessions, prefs, auth tokens — all cookies under the hood.
Reading Cookies
The browser sends one Cookie header:
Cookie: theme=dark; session=abc123; locale=en Parse it:
function parseCookies(header = "") {
return Object.fromEntries(
header.split("; ").filter(Boolean).map((kv) => {
const i = kv.indexOf("=");
return [kv.slice(0, i), decodeURIComponent(kv.slice(i + 1))];
})
);
}
createServer((req, res) => {
const cookies = parseCookies(req.headers.cookie);
res.end(`theme: ${cookies.theme}`);
}).listen(3000); Setting Cookies
Set-Cookie is the response header:
res.setHeader("set-cookie", "theme=dark; Path=/; Max-Age=2592000; HttpOnly; SameSite=Lax");
res.end(); Set multiple:
res.setHeader("set-cookie", [
"session=abc123; HttpOnly; Secure; SameSite=Lax",
"csrf=xyz789; SameSite=Strict",
]); The Important Attributes
| Attribute | Why |
|---|---|
HttpOnly | JS can’t read it (XSS protection) — use for session tokens |
Secure | Only sent over HTTPS — required in production |
SameSite=Lax | Sent on same-site + top-level GETs (CSRF protection) |
SameSite=Strict | Only same-site (most secure, can break flows) |
Path=/ | Available on the whole site |
Max-Age=N | Expires in N seconds |
Domain=example.com | Available on subdomains |
A Session Cookie
res.setHeader(
"set-cookie",
`session=${token}; HttpOnly; Secure; SameSite=Lax; Path=/; Max-Age=86400`
); HttpOnly + Secure + SameSite=Lax is the modern minimum for
authentication cookies.
In Practice
Hand-parsing is error-prone. Use:
cookie(3KB, pure parse/serialize) — composable- Express’s
cookie-parsermiddleware - Fastify’s
@fastify/cookie
These handle quoting, encoding, and edge cases correctly.
Working With Headers →