What a JSON Web Token actually contains
A JSON Web Token (JWT) is a compact, URL-safe way to carry a set of claims — facts
about a user or request — between two parties. You meet them constantly: they are the bearer
tokens behind most modern login systems, single sign-on flows and stateless APIs. A signed JWT
is three Base64URL strings joined by dots, in the form
header.payload.signature. This decoder unpacks the first two, which are plain
JSON, so you can read exactly what a token is asserting.
How the decoding works
Each segment is encoded with Base64URL, a URL-safe variant of Base64. To turn a segment back into text the tool runs four steps:
- Split the token on the
.character into header, payload and signature. - In each of the first two parts, swap
-back to+and_back to/. - Re-add the dropped
=padding until the length is a multiple of four, then Base64-decode to raw bytes and read them as UTF-8 text. - Parse that text with
JSON.parseand pretty-print it with two-space indentation.
The padding rule is exact: the number of = characters to add is
(4 − len mod 4) mod 4. So a segment of length 22 needs
(4 − 22 mod 4) mod 4 = (4 − 2) mod 4 = 2 padding characters before decoding.
A worked example
Take the classic test token whose payload segment is
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkphbmUgRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ. After
Base64URL decoding it becomes
{"sub":"1234567890","name":"Jane Doe","iat":1516239022}. The iat
claim is the Unix timestamp 1516239022; multiplied by 1000 it becomes a
JavaScript date of Thu, 18 Jan 2018, 01:30:22 UTC. If that token also carried
an exp claim in the past, the status line below the table would read “expired”.
Registered time claims
| Claim | Name | Meaning |
|---|---|---|
iat | Issued At | When the token was created. |
nbf | Not Before | Earliest time the token is valid. |
exp | Expiration | Time after which the token must be rejected. |
All three are seconds since the Unix epoch (1 January 1970 UTC). A token is currently usable
only when nbf ≤ now < exp.