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)

  1. Open the AyeTab JWT Debugger at app.ayetab.com, or on your new tab if you use the AyeTab Chrome extension.
  2. Paste the token into the box.
  3. Read the Header and Payload cards. If the token has an exp claim, the payload card shows whether it is still valid or when it expired, in UTC.
  4. 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:

  • exp is the expiry as Unix seconds. If it is in the past, the token is the reason for your 401.
  • aud is who the token is meant for. A token for the wrong API is refused even when it has not expired.
  • iss is who issued it, useful when staging and production tokens get mixed up.
  • iat and nbf are 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 after Bearer is.
  • Cutting the token short. Long tokens wrap in logs and terminals, and a missing tail breaks the signature part or the payload.
  • Reading exp as 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.

Sources

  1. JWT Decoder Online: Decode JSON Web TokensAyeTab
  2. AyeTabAyeTab
  3. Introduction to JSON Web Tokensjwt.io
  4. JSON Web Token (JWT) Debuggerjwt.io