JWT Deep Dive

JSON Web Tokens (JWTs) appear everywhere in modern authentication — from OAuth access tokens to session management. They're powerful but frequently misused. Understanding their structure and limitations helps you use them safely.

JWT Structure

A JWT consists of three Base64-encoded parts separated by dots:

header.payload.signature

The header specifies the algorithm and token type:

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

The payload contains claims — statements about the user and token:

{"sub": "123", "exp": 1623456789, "role": "admin"}

The signature proves the token hasn't been tampered with. It's created by signing the header and payload with a secret key.

The Validation Checklist

Every JWT must be validated before trusting its contents. Verify the signature using the correct key and algorithm. Check exp (expiration) — reject expired tokens. Verify iss (issuer) matches your expected source. Confirm aud (audience) includes your application. Check nbf (not before) if present.

# Most libraries handle this, but understand what's happening
import jwt

try:
    payload = jwt.decode(
        token,
        public_key,
        algorithms=["RS256"],
        audience="your-app-id",
        issuer="https://auth.example.com"
    )
except jwt.InvalidTokenError as e:
    # Token is invalid - don't trust it
    handle_invalid_token(e)

Security Pitfalls

The "none" algorithm attack: Some libraries accept alg: "none", meaning no signature verification. Always specify allowed algorithms explicitly — never accept whatever the token claims.

Key confusion attacks: RS256 uses asymmetric keys (public/private), while HS256 uses a symmetric secret. An attacker might change the algorithm to HS256 and sign with your public key (which is public). Validate that the algorithm matches what you expect.

No revocation: Once issued, a JWT is valid until it expires. You can't invalidate it early without maintaining a blocklist — which defeats some of JWT's benefits. Keep access tokens short-lived.

Payload is not encrypted: Anyone can decode and read the payload. Never put sensitive data like passwords or credit card numbers in JWTs. The signature prevents tampering, not reading.

When JWTs Make Sense

JWTs excel when you need stateless verification across services — the token contains everything needed to validate it. They're less ideal when you need immediate revocation or when tokens would contain large amounts of data.

See More

Further Reading

Last updated December 26, 2025

You need to be signed in to leave a comment and join the discussion