AldeaCode Logo
Developer How to Decode a JWT: Header, Payload, Signature
Developer May 1, 2026 AldeaCode Architecture

How to Decode a JWT: Header, Payload, Signature

Decode a JWT and read the header, payload and signature in your browser. No upload, no token leak. A 30 second routine for debugging JWT tokens.

What a JWT is, in plain words

A JWT is a string that looks like three random chunks separated by dots: aaa.bbb.ccc.

The first chunk says how the token was signed. The second chunk holds the actual data (who you are, when the token expires). The third chunk is the signature, the proof that nobody tampered with it on the way.

The two first chunks are not encrypted. They are encoded so they fit in a URL or a header, but anyone who has the token can read them. That is why pasting your production token into a random “JWT debugger” online is the exact wrong move: you just gave that website a working session for whichever account the token belongs to.

The fast and safe way is to do it in your own browser. The JWT decoder on AldeaCode runs entirely in your tab. You paste the token, it shows the three pieces formatted, the timestamps converted to readable dates, and nothing leaves your computer.

Reading the header without panicking

The header is a tiny JSON object. Two fields matter when something is going wrong: alg and kid.

alg says how the token is signed. The most common values are HS256 (one shared secret), RS256 and ES256 (a public/private key pair). If alg says none, the token is unsigned. Drop it and call your security team.

kid is a key id. When the issuer rotates keys, kid tells the verifier which one to use. If kid is missing and your verifier supports multiple keys, you have a problem.

The classic bug here is called “algorithm confusion”. An attacker takes a token signed with RS256, swaps the alg to HS256, and signs it with the public key as if it were a secret. If the backend trusts whatever the header says, the forged token passes. The fix is to pin the algorithm on the backend, never trust the token’s word for it.

Reading the payload like a contract

The payload is where the real information lives. The fields you check are short:

  • iss is the issuer. Should be the auth server you trust.
  • aud is the audience. Should be your service, not someone else’s.
  • exp is when the token expires.
  • iat is when it was created.

When debugging, four checks cover most of the bugs:

  1. Is exp in the future on your clock?
  2. Is aud your service?
  3. Is iss somebody you trust?
  4. Are timestamps in seconds, not milliseconds?

The fourth one is the silent killer. Some libraries return milliseconds, most JWT verifiers expect seconds. The token looks valid for thirty thousand years, then suddenly nothing renews and nobody knows why. If you are debugging from a Node service, the JWT decoder for Node.js shows the same parsing logic the jsonwebtoken library applies, and if you need to convert, the timestamp converter on AldeaCode tells you which unit you are looking at and what date it really means.

What the signature actually proves

The signature is what stops anyone from changing the payload. The verifier recomputes the signature using the algorithm in the header, the secret or public key, and the bytes of the header and payload. If the recomputed value matches the third chunk, the token has not been touched.

A few things the signature does not prove:

  • It does not say the token has not expired.
  • It does not say the user has not been logged out.
  • It does not say the token belongs to your service.

You still have to check exp, aud, iss after the signature passes. A valid signature only tells you the token came from the issuer untouched.

If you want to peek at the raw signature bytes (for example to confirm a length matches the algorithm), decode the third chunk with the base64 encoder. HS256 signatures are 32 bytes, RS256 are 256 bytes, ES256 are 64. A different length means something mangled the token in transit.

A 30 second routine

When a token misbehaves:

  1. Paste it into the JWT decoder, or the Python flavor if you are debugging a PyJWT service.
  2. Read alg first. Anything weird, stop and audit.
  3. Check exp is in the future, and iat is in the recent past.
  4. Confirm aud is your service and iss is your auth server.
  5. If everything looks valid and it still fails, the bug is on the verifier side, not in the token.

Three rules for working with JWTs day to day: never paste production tokens into a tool you do not control, always pin the algorithm on the backend, and treat the four payload checks above like a checklist instead of a guess. The decoder, the timestamp converter and the base64 encoder all run in your browser, no upload, no log, no servers in the loop.

What we do

Honest sites. No shortcuts.

Real engineering, careful design. Liked the post? Let's talk about your project.

Get in touch →

You might also like

Browse all articles →