What a JWT Looks Like
A JWT (JSON Web Token) is a string of three parts joined by dots. You meet it daily in API auth headers as Authorization: Bearer eyJhbGci... — and knowing its internals makes debugging much faster.
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9 ← Header
.eyJzdWIiOiIxMjM0IiwiZXhwIjoxNzUyNDg5NjAwfQ ← Payload
.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c ← Signature
The first two parts are URL-safe Base64-encoded JSON that anyone can decode — paste the payload into the Base64 encoder and read it immediately. Only the third part, the signature, cannot be produced without the secret key.
Reading the Standard Claims
| Claim | Meaning | Debugging use |
|---|---|---|
exp | Expiry (Unix seconds) | The #1 cause of 401s — compare with current time |
iat | Issued at | When the token was created |
nbf | Not valid before | Rejected before this time — clock-skew issues |
iss / aud | Issuer / audience | Detect tokens from the wrong environment (staging vs prod) |
sub | Subject (user ID) | Whose token this is |
exp is a Unix timestamp — drop it into the timestamp converter for a human-readable time. Most "why is my token rejected?" questions are answered by exactly these two steps.
What the Signature Guarantees
The signature guarantees the token was issued by the holder of the key and has not been altered — change one character of header or payload and verification fails. Algorithms come in two families:
| Family | Typical | Key structure | Fits |
|---|---|---|---|
| HMAC (symmetric) | HS256 | Same secret signs and verifies | Auth within a single service |
| Public-key (asymmetric) | RS256, ES256 | Private key signs, public key verifies | Many services verifying (microservices, OAuth) |
Non-Negotiable Practices
- No secrets in the payload — decoding is not decryption. Passwords, national IDs, or internal permission maps in a token are simply public.
- Reject
alg: none— the classic attack flips the header algorithm to none to bypass verification. Servers must whitelist allowed algorithms. - Keep expiry short — access tokens in minutes (15–60), with renewal delegated to refresh tokens.
- Never log full tokens — a leaked log is a hijacked session. If you must log, keep the first ~8 characters.
Token Debugging Checklist
- Split on dots; decode the second part with the Base64 encoder
- Convert
expwith the timestamp converter and check expiry - Verify
iss/audmatch the target environment - If all looks right, inspect server-side verification: keys, allowed algorithms, clock-skew tolerance
All decoding happens inside your browser, so production tokens never leave your machine. Base64 mechanics are covered in the Base64 encoding guide.
FAQ
Isn't decoding a JWT a security problem?
Decoding is by design. JWT integrity relies on the signature (tamper-proofing), not encryption — which is exactly why secrets must never be placed in the payload.
Can I check expiry without the server?
Yes — decode the exp claim and compare with the current time. What only the server knows is whether the token was additionally revoked (logout, ban).
Why use JWT instead of session cookies?
Servers can verify the token without a session store, which makes horizontal scaling easy. The trade-off: immediate revocation after issue is hard.