What's Inside a JWT? A Tester's Guide to Decoding Tokens
If you test APIs, you handle JSON Web Tokens all day — in Authorization headers, in cookies, in webhook payloads. Most testers treat them as opaque strings, which means missing a whole class of easy-to-find auth bugs. A JWT isn't opaque at all: it's three Base64-encoded parts separated by dots — a header, a payload of claims, and a signature.
Look inside
Paste any token into the JWT Decoder and you'll see the decoded header (the algorithm), the payload (the claims), and a live check of whether the token is expired. The claims are where the test material lives:
exp/iat— expiry and issued-at. Is the lifetime what the spec says? Does the API actually reject the token afterexp?sub— the user the token belongs to. Does using user A's token on user B's resources really fail?aud/iss— audience and issuer. Will a token minted for one service work against another? It shouldn't.role/scope— permissions. The decoder shows you exactly what the server thinks this user may do, which is the starting point for privilege tests.
The test cases this unlocks
- Expired token → expect 401 (not 403, and definitely not 200).
- Tampered payload — change one character in the middle section → the signature no longer matches → expect 401.
- Missing token → 401 with a helpful error body.
- Valid token, insufficient role → 403. If you get 401, the API is conflating authentication with authorization.
Signatures and webhooks
The signature is an HMAC (or asymmetric signature) over the first two parts. You can't verify a production token without its secret — that's the whole point — but when you're testing webhook signatures in a test environment where you do hold the shared secret, the HMAC Generator lets you compute the expected signature for a payload and confirm the receiving code validates it correctly. The Base64 Decode handles any other encoded blobs you meet along the way.
