Guides Security

How JSON Web Tokens (JWT) Work

The three parts of a JWT with a real decoded example, the registered claims, how servers verify the signature, HS256 versus RS256 and the pitfalls to avoid.

Last reviewed:

AdSense Placeholder
Slot: header_reference_page
On this page

A JSON Web Token (JWT, pronounced "jot") is a compact, signed string that carries a few facts, called claims, from one party to another. Servers hand them out after you log in, and your app sends the token back with each request to prove who you are, without the server keeping a session. Decode any token with the JWT Decoder, or make one with the JWT Generator & Verifier.

Three parts, separated by dots

A JWT looks like header.payload.signature. Each part is Base64 in its URL-safe form. Here is a real token made with the secret secret:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkFuYSIsImlhdCI6MTcwMDAwMDAwMCwiZXhwIjoxNzAwMDAzNjAwfQ.K5CXsF2jBQ9-Pr4xg7yeVj3Vr-Be0jvTHInQnYK-aSk

Header (eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9) decodes to:

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

Payload (eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkFuYSIsImlhdCI6MTcwMDAwMDAwMCwiZXhwIjoxNzAwMDAzNjAwfQ) decodes to:

{"sub":"1234567890","name":"Ana","iat":1700000000,"exp":1700003600}

The signature (K5CXsF2jBQ9-Pr4xg7yeVj3Vr-Be0jvTHInQnYK-aSk) is computed over the first two parts with the algorithm and key named in the header. HS256 is HMAC with SHA-256: whoever knows the secret can both create and check it.

Registered claims

Claim Meaning
iss Issuer: who created the token
sub Subject: who the token is about, usually a user ID
aud Audience: which service the token is meant for
exp Expiration time (Unix seconds); reject the token after it
nbf Not before: reject the token until this time
iat Issued at: when the token was created
jti JWT ID: a unique identifier, useful for revocation lists

Times are in seconds since 1970 (see the Unix Timestamp Converter): the token above was issued at 1700000000, which is 14 November 2023, and expires an hour later.

How a server checks a token

  1. Split the token into its three parts and decode the header.
  2. Recompute the signature over header.payload with the expected algorithm and key, and compare it with the one in the token. A different secret fails: the token above verifies with secret and is rejected with anything else.
  3. Check the claims: exp has not passed, nbf has, and iss and aud are the expected values.

Signing algorithms

  • HS256 / HS384 / HS512 use one shared secret. Simple, but every service that verifies tokens can also forge them.
  • RS256 / ES256 use a private key to sign and a public key to verify, so you can share the public key widely. Prefer these when many services verify tokens issued by one.

Pitfalls

  • A JWT is signed, not encrypted. Anyone can read the payload by decoding it. Never put passwords or secrets in it.
  • Always fix the algorithm on the server. Accept only the algorithm you expect. Trusting the alg field has led to attacks, such as the header {"alg": "none"} that some libraries once accepted as "no signature required".
  • Set a short exp. A stolen token works until it expires. Use short lifetimes plus refresh tokens.
  • A token cannot be revoked by itself. Once issued it stays valid until exp. If you need instant logout, keep a denylist of jti values or use server-side sessions instead.
  • Store tokens carefully. Tokens in localStorage are readable by any script on the page, so an XSS bug exposes them; an HttpOnly cookie is harder to steal.
  • Use a long random secret for HMAC, not a word like secret. The example here is for demonstration only.

See JWT and HMAC.

Try these tools

See also

  • Glossary JWT
    A JWT (JSON Web Token) is a compact, signed token made of three Base64URL parts that carries claims such as who a user is and when the.
  • Glossary HMAC
    HMAC (hash-based message authentication code) is a hash computed with a secret key.
  • Glossary Base64
    Base64 is an encoding that writes any binary data using only 64 safe text characters (A-Z, a-z, 0-9, + and /).
  • Guide How Base64 and Encoding Work
    What encoding is (and is not), how Base64 turns three bytes into four characters, why it adds a third, and the mistakes to avoid.

Frequently Asked Questions

Yes. The header and payload are only Base64-encoded, not encrypted. The signature stops people changing them undetected, but not reading them.

AdSense Placeholder
Slot: footer_leaderboard