Technical
JWT
Also called JSON Web Token.
JWT is a compact signed token made of three base64url parts, header, payload, and signature, that carries claims such as user id and expiry. A server can verify it without looking anything up.
How it is measured
Split on the dots and base64-decode the first two parts. The header names the algorithm (`HS256`, `RS256`) and the payload lists claims like `sub`, `iat`, and `exp`. Anyone holding the token can read the payload; only the signature is protected.
Verify in order: the signature is valid, the algorithm is on your allowlist, `exp` is in the future, and `iss` and `aud` match. Time claims are Unix seconds, so allow 30 to 60 seconds of clock skew.
Worked example
An API issues a JWT with `iat` 1790000000 and `exp` 900 seconds later. A client calls at 1790000840 and passes. At 1790000910 the same token returns 401 with token expired, and the client trades its refresh token, stored in an HttpOnly cookie, for a new one.
A penetration tester then edits the header to `alg: none` and strips the signature. A library on default settings accepts it. The server is patched to require RS256 and reject anything else.
How it differs
A JWT carries its own claims and is verified by signature. OAuth is the process that gets a token to a client. OAuth may issue a JWT or an opaque random string. One is a format and the other is a protocol.
Common errors
Putting secrets or personal data in the payload, which is only encoded. Accepting `alg: none`. Issuing tokens that never expire. Storing one in localStorage where any XSS can read it. Having no way to revoke before expiry. Signing with a short guessable HMAC secret.
In practice
Keep lifetimes to minutes, pin one algorithm, put nothing private in the payload, and carry the token in an HttpOnly cookie. Decide in advance how you will revoke: short expiry with refresh rotation, or a denylist of token ids.