Key takeaways
- A JWT's header and payload are Base64-URL encoded JSON, so they can be read without any key.
- The fastest method is a local browser tool: the free AyeTab JWT Debugger decodes without uploading the token and shows its expiry.
- Decoding does not prove a token is genuine; only a signature check with the right key does.
Here is how to decode JWT tokens: split the token at its two dots and Base64-URL decode the first two parts. The first is the header and the second is the payload, both plain JSON. The quickest route is a local browser tool such as the free AyeTab JWT Debugger; the terminal and a few lines of code work too.
What you are decoding
A signed JSON Web Token has the form xxxxx.yyyyy.zzzzz:
| Part | Holds | Readable after decoding |
|---|---|---|
| Header | The algorithm (alg) and type (typ) |
Yes |
| Payload | Claims such as sub, iss, aud, exp, iat and custom fields |
Yes |
| Signature | A value made from the header, payload and a key | No, it is binary |
Base64-URL is an encoding, so no key is needed to read the first two parts. That is also why a token should never carry a password or other secret in its payload.
Before you start, strip anything that is not the token. If you copied it from a request, remove the Bearer prefix and any quotes.
Method 1: in the browser (fastest)
- Open the AyeTab JWT Debugger at app.ayetab.com, or on your new tab if you use the AyeTab Chrome extension.
- Paste the token into the box.
- Read the Header and Payload cards. If the token has an
expclaim, the payload card shows whether it is still valid or when it expired, in UTC. - Use the copy button on any card to grab the JSON.
The decoding runs in the page, so the token is not uploaded to AyeTab's servers. You do not need an account, and the page keeps working offline once loaded. If the box says the token needs three dot-separated parts, part of the string is missing.
Method 2: in the terminal
On Linux or macOS, take the second part and translate the URL-safe characters back to standard Base64:
TOKEN='eyJhbGciOi...'
echo "$TOKEN" | cut -d. -f2 | tr '_-' '/+' | base64 -d
Base64-URL drops the = padding, so base64 may print the JSON and then warn about invalid input. Add one or two = to the end of the part if that bothers you. Pipe the output to jq . to indent it.
Method 3: in code
JavaScript in a browser or Node:
const part = token.split(".")[1].replace(/-/g, "+").replace(/_/g, "/");
const payload = JSON.parse(atob(part));
Python:
import base64, json
part = token.split(".")[1]
payload = json.loads(base64.urlsafe_b64decode(part + "=" * (-len(part) % 4)))
Most JWT libraries also have a decode function that skips verification. Use it for logging and debugging only, never to make an access decision.
Reading the result
A few claims answer most questions:
expis the expiry as Unix seconds. If it is in the past, the token is the reason for your 401.audis who the token is meant for. A token for the wrong API is refused even when it has not expired.issis who issued it, useful when staging and production tokens get mixed up.iatandnbfare when it was issued and when it becomes usable.
Common mistakes
- Pasting the whole header.
Authorization: Bearer eyJ...is not a token; only the part afterBeareris. - Cutting the token short. Long tokens wrap in logs and terminals, and a missing tail breaks the signature part or the payload.
- Reading
expas milliseconds. JWT times are in seconds since 1970, while JavaScript dates use milliseconds, so multiply by 1,000 before building a date. - Decoding the signature. The third part is raw bytes, not JSON, so it will look like noise.
Decoding is not verifying
Anyone can decode a JWT, and anyone can write a fake one that decodes cleanly. Proof that a token is genuine comes only from checking its signature with the right secret or public key, which your server or auth library should do on every request. AyeTab reads tokens and does not verify them; for a manual signature check, the debugger on jwt.io accepts a secret, and you should use a test key there rather than a production one.
For the everyday question of what is inside this token, the browser method with AyeTab is the shortest path, and it keeps the token on your machine.
Frequently asked questions
Do I need the secret key to decode a JWT?
No. The header and payload are only encoded, not encrypted. The key is needed to verify the signature, not to read the claims.
Why does base64 fail on my JWT?
JWTs use Base64-URL, which swaps two characters and drops the padding. Translate '-' and '_' back to '+' and '/', and add '=' padding if your tool needs it.
How do I see when a JWT expires?
Read the exp claim, which is in Unix seconds. The AyeTab JWT Debugger converts it for you and shows whether the token is still valid.