How cookie-session authentication works
session lifecycle, session ID, server-side session store, Set-Cookie header, session cookie vs persistent cookie, session fixation
The Session Lifecycle
When a user logs in, your server creates a session: a record stored server-side that maps a random ID to the user's identity. That ID travels to the browser as a cookie. On every subsequent request, the browser sends the cookie, your server looks up the session by ID, finds the user identity, and the request is considered authenticated.
The user never sees their own user ID or any sensitive data. They only have a random, opaque session ID that is meaningless without the server-side store.
Session Cookie vs Persistent Cookie
A session cookie has no expiry date and is deleted when the browser closes. A persistent cookie has an explicit expires or max-age attribute and survives browser restarts — the basis of "remember me" functionality.
Session Fixation
Session fixation is an attack where an attacker pre-sets a known session ID before the user logs in, then hijacks the session after login. The defense is simple: always regenerate the session ID on login. Any session that existed before authentication must be replaced with a fresh one after credentials are verified.
// After verifying credentials
req.session.regenerate((err) => {
if (err) return next(err);
req.session.userId = user.id;
res.json({ message: 'Logged in' });
});
