Dmytro Morar
Auth

JWT Cookies vs. LocalStorage

The storage location of a token directly impacts the security of the application. The primary choice is between HttpOnly cookies, which are protected from JavaScript, and LocalStorage, which is accessible from client-side code.

1. Cookies

Features:

  • The token is stored in a cookie and is automatically sent by the browser with every request.
  • If the cookie is marked with the HttpOnly flag, it is inaccessible from JavaScript.
  • It can have flags:
    • Secure — transfer only over HTTPS
    • SameSite — restriction of cross-site requests
    • Expires / Max-Age — expiration period

Advantages:

  • Protection against XSS (since the token is inaccessible from JS).
  • Simple integration with SSR and browser requests.
  • Suitable for refresh tokens or session cookies.

Disadvantages:

  • Susceptible to CSRF attacks if SameSite is not configured.
  • Not suitable for mobile clients without cookie storage.

2. LocalStorage

Features:

  • Manual storage of the token in the browser (localStorage.setItem('token', ...)).
  • The token is retrieved and added to the Authorization: Bearer <jwt> header with every request.

Advantages:

  • Simplicity of implementation for SPA and REST APIs.
  • Full control over when and how the token is sent.
  • Not automatically sent by the browser → no CSRF.

Disadvantages:

  • Susceptible to XSS — any malicious script can read the token.
  • No automatic expiration period.
  • Requires additional security measures (CSP, sanitization, logout flow).

3. Alternative — Memory Storage

  • Storing the token only in memory (RAM) during the session.
  • Reset when the page is refreshed → increased security.
  • A compromise between convenience and protection (often used with silent refresh).

Security Recommendations

Token TypeWhere to StoreReason
Access TokenIn memory or LocalStorageFast access from JS is needed
Refresh TokenIn HttpOnly cookieMaximum protection against XSS

Summary

  • Cookies (HttpOnly) — more secure but require CSRF protection.
  • LocalStorage — simpler but vulnerable to XSS.
  • In practice: Access Token in memory, Refresh Token in HttpOnly cookie — a balance between UX and security.

On this page