Guides Pricing

Guide

How JWT authentication works

A plain-English guide to JSON Web Tokens — how they are structured, signed, and verified — with a decoder built in so you can inspect your own token.

Try it — JWT Decoder
J
JWT Decoder
Secret

A JSON Web Token (JWT) is a compact, self-contained way to carry claims — usually "who this user is" — between a client and a server. After you log in, the server hands you a token; you send it back on each request, and the server trusts it because it can verify the token was not tampered with. Paste any token into the decoder above to follow along.

The three parts

A JWT is three Base64URL-encoded sections joined by dots: header.payload.signature.

  • Header — the token type and the signing algorithm, e.g. { "alg": "HS256", "typ": "JWT" }.
  • Payload — the claims, e.g. { "sub": "123", "name": "Ada", "exp": 1735689600 }.
  • Signature — a cryptographic signature over the header and payload, made with a secret or private key.

The header and payload are encoded, not encrypted. That is the single most important thing to understand: anyone holding the token can decode and read them. The security comes from the signature, not from hiding the contents.

How signing and verification work

When the server issues a token, it computes the signature like this (for HS256):

HMAC-SHA256( base64url(header) + "." + base64url(payload), secret )

On every later request, the server recomputes that signature from the token's header and payload using its own secret and compares it to the signature in the token. If they match, the token is authentic and untouched. If even one character of the payload was changed, the signatures differ and the token is rejected. The decoder above can verify an HS256/384/512 token if you paste the secret.

Common claims

  • sub — the subject (typically the user id).
  • iatissued at, a Unix timestamp.
  • expexpires at, a Unix timestamp; after this time the token is invalid.
  • iss / aud — the issuer and intended audience.

Keep payloads small and never include passwords, secrets, or anything you would not want the client to read.

Security do's and don'ts

  • Do set a short exp and use refresh tokens for long sessions.
  • Do verify the signature and the exp, iss, and aud on every request.
  • Don't accept the alg from the token blindly — pin the algorithm server-side to avoid "alg: none" and algorithm-confusion attacks.
  • Don't store secrets in the payload — it is readable by anyone.

Once you understand the three parts and the signature, JWTs stop being mysterious: they are just signed JSON. Use the decoder above to inspect a real token, check its expiry, and verify its signature.

Frequently asked questions

No. A standard JWT is signed, not encrypted. The header and payload are only Base64URL-encoded, so anyone with the token can read them. Never put secrets in a payload.
The signature. If a single byte of the header or payload changes, the signature no longer matches, and the server rejects the token. Only a party with the signing key can produce a valid signature.
For browser apps, an HttpOnly, Secure cookie is the safest common choice, as it is not readable by JavaScript. localStorage is easier but exposes the token to any XSS on the page.
HS256 uses one shared secret for both signing and verifying (symmetric). RS256 uses a private key to sign and a public key to verify (asymmetric), which is better when many services only need to verify.
Decode it and read the exp claim, a Unix timestamp. If exp is in the past, the token is expired. The decoder above shows exp and iat for any token you paste.

Related

Esc
↑↓ navigate open Esc close