Cookies, Sessions, and Local Storage: What's Actually Stored Where
Three different browser storage mechanisms, three different actual use cases — and the specific reason auth tokens belong in one of them and not the others.
"Where do I store the auth token" is a question with a real, specific right answer that depends on understanding what each storage mechanism actually does differently — not a matter of preference.
Cookies
Set by the server (via a `Set-Cookie` header) or by JavaScript, and — critically — sent automatically by the browser on every subsequent request to that domain, without any code needing to attach them manually. A cookie marked `HttpOnly` is invisible to JavaScript entirely, readable only by the browser's own request mechanism — a real, meaningful defense against a cross-site-scripting attack stealing it, since injected malicious JS simply cannot read it.
sessionStorage and localStorage (the Web Storage API)
Both are key-value stores accessible only via JavaScript — never sent automatically with requests. `sessionStorage` clears when the tab closes; `localStorage` persists until explicitly cleared, across browser restarts. Neither is encrypted or specially protected — anything in either is readable by any JavaScript running on that page, including an injected malicious script.
The actual right answer for an auth token
An `HttpOnly` cookie is the safer default for a session token specifically because it's invisible to JavaScript — a real defense against XSS stealing it outright. A token in `localStorage` is fully readable by any script on the page, which means any XSS vulnerability anywhere on the site becomes a full session-theft vulnerability too. The tradeoff: cookies bring their own attack surface (CSRF — a malicious site tricking the browser into sending your cookie along with a forged request), which needs its own defense (a CSRF token, or the `SameSite` cookie attribute) — but that's a well-understood, addressable problem, unlike XSS-readable storage, which has no equivalent mitigation once the token is in `localStorage`.
The practical takeaway
Use `HttpOnly` cookies (with `SameSite` set appropriately) for anything security-sensitive like a session token; use `localStorage` for genuinely non-sensitive client-only preferences — a UI theme, a collapsed sidebar state, a draft the user hasn't submitted yet. This exact site uses `localStorage`-style guidance for exactly that kind of low-stakes preference, and never for anything an attacker gaining read access to would actually matter.