What the Base64URL decoder does
It converts - to + and _ to /, adds the missing = padding, and decodes the bytes. Standard Base64 is accepted too, so you do not need to know which kind you have. The result is shown as UTF-8 text. If the text is valid JSON, it is pretty-printed (you can switch this off). If the data is binary, you see a hex dump instead.
Reading a JWT
A JSON Web Token has three parts separated by dots: header.payload.signature. The header and the payload are Base64URL-encoded JSON. When you paste a token, the tool decodes both and lists the claims:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9 .eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ .SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
The header decodes to {"alg":"HS256","typ":"JWT"} and the payload to {"sub":"1234567890","name":"John Doe","iat":1516239022}. Standard claims are explained, and the time claims are shown as UTC dates:
| Claim | Meaning |
|---|---|
iss | Issuer: who created the token |
sub | Subject: who the token is about, usually a user id |
aud | Audience: who the token is for |
exp | Expiry time (Unix seconds) |
nbf | Not valid before this time |
iat | Issued at |
jti | Unique id of the token |
Important: decoding is not verifying
Anyone can read the payload of a JWT, and this page does not check the signature. Never trust the content of a token because it decodes well. Servers must verify the signature and the claims (exp, aud, iss). Do not put secrets in a JWT payload, because it is only encoded. Do not paste live production tokens into tools you do not trust. This page works in your browser and sends nothing, but tokens in use are best handled with care.
Why Base64URL decoding fails in other tools
- The library expects padding and the token has none. Add
=until the length is a multiple of 4. - The library expects the standard alphabet and the data contains
-or_. Convert them first. - A length that leaves exactly one extra character is never valid, and means the text is cut.
Decode in code
// Node.js
Buffer.from(s, 'base64url').toString('utf8');
// JavaScript (browser)
const b = s.replace(/-/g, '+').replace(/_/g, '/');
atob(b + '='.repeat((4 - b.length % 4) % 4));
# Python
import base64
base64.urlsafe_b64decode(s + '=' * (-len(s) % 4))
Related: Base64URL encode, the JWT encoder, the Base64 decoder and What is Base64?