A JWT looks like three blobs of gibberish separated by dots: eyJhbGciOi....eyJzdWIiOi....SflKxwRJ.... Each blob has a job, and understanding the three jobs explains both why JWTs conquered API authentication and which mistakes keep causing breaches.
The three parts
- Header — JSON describing the token itself, typically
{"alg":"HS256","typ":"JWT"}. It names the signing algorithm so the verifier knows how to check the token. - Payload — JSON carrying the claims: who this token is about (
sub), who issued it (iss), when it expires (exp), plus whatever custom fields the application needs. - Signature — the verifier's proof. The issuer signs
header.payloadwith a secret (HMAC) or private key (RSA/ECDSA). Anyone holding the key can confirm the token is genuine and unmodified.
Header and payload are Base64URL-encoded, not encrypted. Anyone can read them — decode any token and the claims are right there. The signature provides integrity, not confidentiality.
The bigger question behind this post: How to Remain Valuable When Intelligence Becomes Cheap — which human, economic, and strategic advantages stay scarce when AI does the work. A 224-page practical book, $3.84. Read it on Gumroad →
What JWTs do and don't guarantee
A valid signature proves the token was issued by someone holding the key and hasn't been altered since. That's it. It does not mean the token hasn't been stolen (a replayed JWT works fine until exp), it doesn't revoke itself when a user logs out, and it doesn't protect the payload from readers. Short expirations, refresh-token rotation, and never putting secrets in claims are how production systems handle those gaps.
The classic vulnerabilities
Two JWT failures appear in breach reports repeatedly. The alg:none attack: verifiers that accept tokens declaring no signature at all — always reject those. And algorithm confusion: verifiers tricked into checking an RSA signature with HMAC using the public key as the secret — always pin the expected algorithm. Both are verifier bugs, not token bugs, which is why JWT libraries must be configured strictly, never on defaults you haven't read.
Inspect any token
Paste a token into the JWT decoder & analyzer to see its header, claims, and expiry decoded instantly — in your browser, so test credentials in the payload never transit a server. It's the fastest way to answer "why is this request unauthorized," and a good habit before trusting any token you didn't mint yourself.