DevToolbox
All guidesDevToolbox guide

JSON Web Tokens (JWT) Explained: Architecture & Security

A comprehensive technical guide to JSON Web Tokens (RFC 7519). Learn header and payload structure, digital signatures, common security flaws, and best practices.

What Is a JSON Web Token?

JSON Web Token (JWT) is an open standard (RFC 7519) that defines a compact, self-contained method for securely transmitting claims between parties as a JSON object. This information can be verified and trusted because it is digitally signed. JWTs can be signed using a secret (with the HMAC algorithm) or a public/private key pair using RSA or ECDSA.

The Three Components of a JWT

A JWT appears as three Base64URL-encoded strings separated by periods:

header.payload.signature

1. Header

The header typically contains two fields: the signing algorithm being used (such as HS256, RS256, or ES256) and the type of token (which is "JWT"):

{
  "alg": "HS256",
  "typ": "JWT"
}

2. Payload

The payload contains the claims. Claims are statements about an entity (typically, the authenticated user) and additional metadata:

  • Registered claims: Predefined claims that are recommended to provide interoperability: iss (issuer), exp (expiration time), sub (subject), aud (audience), nbf (not before), iat (issued at).
  • Public claims: Custom claims defined by application developers, typically registered in the IANA JSON Web Token Registry or named with collision-resistant namespaces.
  • Private claims: Custom claims agreed upon by the producer and consumer of the token, such as role: "admin" or organization_id: "org_123".

3. Signature

To create the signature part, you take the encoded header, the encoded payload, a secret key, and the algorithm specified in the header, and sign them:

HMACSHA256( base64UrlEncode(header) + "." + base64UrlEncode(payload), secret )

Critical JWT Security Vulnerabilities to Avoid

  • The "alg: none" Exploit: Some flawed verification libraries historically allowed tokens with "alg": "none", accepting unsigned forged tokens. Always reject tokens with algorithm "none" in production.
  • Algorithm Confusion (HMAC vs RSA): If a server expects an asymmetric RSA public key but the attacker supplies an HS256 token signed with the server's public key as an HMAC secret, poorly written libraries can accept the spoofed signature. Explicitly specify the permitted algorithms on your server.
  • Storing Sensitive Secrets in Payloads: Remember that JWT payloads are only encoded in Base64URL, not encrypted! Anyone who intercepts the token can read the claims. Never store database passwords, API tokens, or credit card numbers in a JWT payload.
  • Indefinite Lifespans: Always configure reasonable exp timestamps (e.g., 15 minutes for access tokens) coupled with secure, rotating refresh tokens stored in HTTP-only, SameSite cookies.

Frequently Asked Questions About JWT

Where should I store JWTs in a web browser?

The most secure storage location for authentication JWTs is an HTTP-only, Secure, SameSite=Lax (or Strict) cookie. Storing tokens inside browser localStorage or sessionStorage exposes them to Cross-Site Scripting (XSS) attacks; any third-party script or compromised dependency can read localStorage and steal the token. HTTP-only cookies cannot be accessed by client-side JavaScript, mitigating XSS token theft.

How do I revoke or invalidate a JWT before it expires?

Because standard JWTs are stateless, once signed they remain valid until their exp timestamp passes. To support instant revocation (e.g., when a user logs out or changes their password):

  • Short-lived access tokens: Configure access tokens with very brief lifetimes (5 to 15 minutes), paired with stateful refresh tokens stored in a database or Redis cache.
  • Token Blocklists: Store revoked token IDs (jti claim) in a high-speed in-memory store like Redis until their original expiration passes.
  • Token Versioning: Store a token_version integer on the user's database record and include it in the JWT claims; incrementing the version instantly invalidates all previously issued tokens.

What is the difference between JWS, JWE, and JWT?

JWT (JSON Web Token) is the overarching data format. JWS (JSON Web Signature) signs the content so its integrity is verifiable, but leaves the payload readable in Base64URL text. JWE (JSON Web Encryption) encrypts the payload so that only authorized parties possessing the decryption key can read the claims.

Try the related tool

JWT Decoder

More guides