In one sentence
A JWT is a compact, URL-safe token made of three Base64url parts — a header, a JSON payload of claims, and a signature — that lets a server hand a client a set of verified facts (who you are, when it expires) it can check later without a database lookup.
Why it matters
JWTs are how most modern APIs carry identity. After you log in, the server signs a small JSON blob ("subject 42, admin, expires at 15:00") and hands it back; you present it on every request, and the server just verifies the signature instead of hitting the session store. That statelessness is the whole appeal — and the whole footgun.
The single most important thing to internalise: a signed JWT is authenticated, not encrypted. Anyone holding the token can read every claim in it — the parts are merely Base64url-encoded, not hidden. So a JWT is safe to trust (the signature stops tampering) but never a place to put a secret, and stealing one is as good as stealing the session.
How it is structured
A JWT is three Base64url strings joined by dots: header.payload.signature.
- The header names the algorithm, e.g.
{"alg":"HS256","typ":"JWT"}.HS256is a symmetric HMAC with a shared secret;RS256is an RSA signature with a public/private key pair. - The payload is a set of claims. Registered ones include
iss(issuer),sub(subject),aud(audience),exp(expiry, a Unix timestamp) andnbf(not-before). You can add your own. - The signature is computed over the first two parts with the secret or private key. Change one character of the payload and the signature no longer verifies.
Verification means two things, and both matter: the signature checks out and the claims are acceptable (not expired, right audience, right issuer). A token can have a perfect signature and still be invalid because exp has passed.
Try it yourself hands-on
You pulled a bearer token off a request and want to know what it asserts and whether it is safe.
- Open the JWT Decoder and click Load Sample (or paste your token). The header, payload and signature split out instantly, and the Claim Analysis panel resolves
exp/nbfto real dates and flags an expired token — all in your browser; nothing is sent anywhere. - Watch the Security Warnings. If the header says
alg: none, the tool flags "this token has no signature verification!" — the classic algorithm-bypass attack where a client strips the signature and hopes the server trusts it. Any server acceptingalg:noneis broken. - Test the secret's strength: paste your HMAC secret and use Verify Signature (HMAC). If a short, guessable secret verifies an
HS256token, an attacker can brute-force it offline and mint their own admin tokens. Then flip it around — Sign a JWT (HMAC) lets you forge a token with your own claims to prove to yourself how little stands between a weak secret and full impersonation. - For the raw signing primitive behind
HS256, the HMAC Generator shows exactly what is being computed overheader.payload.
Result: you can read any token's claims, spot the alg:none and weak-secret traps, and explain why "just decode it" is not the same as "verify it".
Common misreadings
- Decoding is not verifying. Reading the payload is trivial and proves nothing; only checking the signature (and the claims) tells you the token is genuine and current.
- Never trust the
algheader blindly. Pin the expected algorithm server-side. Acceptingnone, or letting an attacker switchRS256toHS256and sign with the public key as the HMAC secret, are both real, repeated CVEs. - You cannot un-issue a JWT. Because it is stateless, a stolen token is valid until
exp. Keep lifetimes short and pair with a revocation list or refresh-token flow when that matters.