ctx.cookies, Signed Cookies, and Security Flags
Cookies in Koa
Koa's built-in ctx.cookies API lets you read and write cookies with full control over security flags. Signed cookies use app.keys so the client cannot forge them.
What you'll learn
- Read and write cookies with ctx.cookies.get and ctx.cookies.set
- Enable signed cookies using app.keys
- Apply httpOnly, secure, and sameSite flags correctly
Koa wraps Node’s http.IncomingMessage cookie header and http.ServerResponse
Set-Cookie header in a clean ctx.cookies API backed by the
cookies package. No extra installation is needed.
Reading and Writing
// Set a cookie
ctx.cookies.set("theme", "dark", {
maxAge: 30 * 24 * 60 * 60 * 1000, // 30 days in ms
httpOnly: false, // safe for JS to read (theme preference)
secure: process.env.NODE_ENV === "production",
sameSite: "lax",
});
// Read a cookie
const theme = ctx.cookies.get("theme"); // "dark" | undefined Signed Cookies
A signed cookie appends an HMAC-SHA256 signature so the server can detect tampering. The client still sees the value, but cannot change it without invalidating the signature.
Step 1: Set app.keys.
app.keys = [process.env.COOKIE_KEY_1, process.env.COOKIE_KEY_2]; Step 2: Pass signed: true when writing and reading.
// Write
ctx.cookies.set("userId", "42", { signed: true, httpOnly: true });
// Read — returns undefined if the signature is invalid
const userId = ctx.cookies.get("userId", { signed: true }); Koa stores two cookies: userId (the value) and userId.sig (the signature).
It verifies against all keys in app.keys, so you can rotate keys safely.
Security Flag Reference
| Flag | Recommended value | Why |
|---|---|---|
httpOnly | true for auth cookies | Blocks JS access; mitigates XSS cookie theft |
secure | true in production | Cookie only sent over HTTPS |
sameSite | "lax" (default) or "strict" | Blocks most CSRF |
maxAge | Session or explicit ms | Avoid implicit session cookies in production |
signed | true for any sensitive value | Tamper-proof with app.keys |
Cookie vs Session
Use a raw cookie when the data is small, client-readable is acceptable, and you
don’t need server-side revocation (e.g., a user preference or a CSRF token).
Use koa-session when you need revocation, larger payloads, or server-side
data that must not reach the client.
Up Next
Move beyond cookies to stateless authentication with JSON Web Tokens and the
koa-jwt middleware.