How to Store JSON Web Tokens Securely in JavaScript

JSON Web Tokens (JWTs) are an open standard for securely transmitting information between parties as a JSON object, widely used for stateless authentication in modern web applications. This article breaks down the anatomy of a JWT, analyzes the vulnerabilities associated with client-side token storage—specifically Cross-Site Scripting (XSS) and Cross-Site Request Forgery (CSRF)—and explains the most secure strategies for managing JWTs in JavaScript environments.

What is a JSON Web Token (JWT)?

A JSON Web Token is a compact, URL-safe token format consisting of three parts separated by dots (.):

  1. Header: Contains metadata about the token, typically the signing algorithm (e.g., HMAC SHA256 or RSA) and the token type.
  2. Payload: Contains the claims, which are statements about an entity (typically the user) and additional data like expiration timestamps (exp).
  3. Signature: Generated by taking the encoded header, encoded payload, a secret key (or private key), and signing them using the specified algorithm to ensure data integrity.

Because the payload is merely Base64Url-encoded—not encrypted—anyone can decode and read its contents. Therefore, sensitive data such as passwords should never be placed in a JWT payload.

Common Storage Options in JavaScript and Their Risks

1. localStorage and sessionStorage (Web Storage API)

Web Storage is accessible by any JavaScript running on the same domain.

2. Standard Cookies

JavaScript can read and write standard cookies via document.cookie.

3. HttpOnly Cookies

An HttpOnly cookie is set by the server and cannot be accessed by client-side JavaScript via document.cookie.


The Secure Approach: Memory Storage with HttpOnly Refresh Tokens

The current industry standard for handling JWTs in modern JavaScript applications utilizes a two-token architecture:

1. Short-Lived Access Token in JavaScript Memory


Summary of Best Practices