All References

JWT Guide

How JSON Web Tokens work: three-part structure, signing algorithms, standard claims, validation steps, and security pitfalls to avoid.

What is a JWT?

A JSON Web Token (JWT) is a compact, URL-safe token used to represent claims between two parties. It is most commonly used for stateless authentication: the server issues a signed token at login; subsequent requests carry the token, and the server verifies the signature without consulting a database.

A JWT looks like: xxxxx.yyyyy.zzzzz — three Base64URL-encoded sections separated by dots: Header, Payload, Signature.

JWT Structure

Each part is independently Base64URL-encoded (no padding). The three parts are joined with dots:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkphbmUgRG9lIiwiaWF0IjoxNzE2MjM5MDIyLCJleHAiOjE3MTYyNDI2MjJ9
.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

Header

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

alg — the signing algorithm. typ — always JWT.

Payload (Example)

{
  "sub": "1234567890",
  "name": "Jane Doe",
  "role": "admin",
  "iat": 1716239022,
  "exp": 1716242622
}

The payload is not encrypted — anyone can decode it. Never put passwords, credit card numbers, or other secrets here.

Registered Claims

Claim Name Type Description
iss Issuer string Who issued the token (e.g., https://auth.example.com)
sub Subject string The entity the token is about, usually a user ID
aud Audience string | string[] Intended recipient(s) of the token
exp Expiration Time NumericDate Unix timestamp after which the token must be rejected
nbf Not Before NumericDate Token must not be accepted before this Unix timestamp
iat Issued At NumericDate Unix timestamp when the token was issued
jti JWT ID string Unique identifier; useful for preventing replay attacks via a denylist

Signing Algorithms

The signature covers Base64URL(header) + "." + Base64URL(payload). If any bit changes, signature verification fails.

Algorithm Family Key Type Notes
HS256HMACShared secretFast; both sides need the secret — not suitable for public clients
HS384HMACShared secretStronger hash; same key management constraints as HS256
HS512HMACShared secretStrongest HMAC variant
RS256RSARSA key pairSigns with private key; verifies with public key. Best for public APIs / OIDC
RS384RSARSA key pairSame as RS256 with SHA-384 hash
RS512RSARSA key pairSame as RS256 with SHA-512 hash
ES256ECDSAEC key pair (P-256)Smaller signatures than RSA; recommended for modern systems
PS256RSASSA-PSSRSA key pairRSA with probabilistic padding; FIPS-approved alternative to RS256

Validation Steps

  1. Verify the signature using the correct key and the algorithm declared in the header.
  2. Reject alg: none — never accept unsigned tokens unless explicitly designed for it.
  3. Check exp: reject if current time ≥ exp (allow a few seconds of clock skew).
  4. Check nbf (if present): reject if current time < nbf.
  5. Check iss: verify the issuer matches your expected value.
  6. Check aud: verify your service is in the audience list.

Security Best Practices

When to Use JWT (and When Not To)

Good Fit

  • Stateless API authentication
  • Microservices (service-to-service auth)
  • Single Sign-On (OIDC id_token)
  • Short-lived one-time tokens (email verification)

Poor Fit

  • Sessions requiring instant revocation (logout before exp)
  • Storing large amounts of claims (tokens get big)
  • Replacing cookies entirely in browser apps without care

Inspect and decode JWT tokens visually with the JWT Decoder tool.

Frequently Asked Questions

Is a JWT encrypted?

No — a standard JWT (JWS) is only signed, not encrypted. The header and payload are Base64URL-encoded, which anyone can decode in seconds. Signing ensures the data hasn't been tampered with, but doesn't hide it. If you need to hide the payload, use a JWE (JSON Web Encryption) token, or simply don't put sensitive data in the JWT.

What is the difference between HS256 and RS256?

HS256 uses a shared secret — the same key both signs and verifies. This means every service that needs to verify tokens must hold the secret key, creating a security risk. RS256 uses an asymmetric RSA key pair: the auth server signs with the private key, and any service can verify with the public key (safely shareable). RS256 (or ES256) is preferred for public APIs and multi-service architectures.

How do I invalidate a JWT?

JWTs are stateless — you can't truly "delete" one. Options: (1) Short expiration: use a 15-minute access token so compromise windows are small. (2) Token denylist: store invalidated jti values in Redis until their natural expiry. (3) Refresh token rotation: keep short-lived access tokens and server-side revocable refresh tokens. For immediate revocation at scale, option 2 or 3 is required.