QuikTool

What is a JWT and how to decode one

A JSON Web Token, or JWT, is a compact piece of text that says who you are and what you may do. Websites and APIs hand one out after you sign in and ask for it back with each request. It looks like random characters, but you can read what is inside it.

Try it now: JWT Decoder, Base64 Encode / Decode, Unix Timestamp Converter.

The three parts of a JWT

A JWT is three pieces separated by dots: header.payload.signature. The header and the payload are JSON that has been written in Base64URL, a variant of Base64 that is safe in web addresses. The signature is a fingerprint made with a secret or a private key.

  • The header says how the token is signed, for example the algorithm HS256, and that its type is JWT.
  • The payload holds the claims: facts about the user and the token.
  • The signature lets the server check that the header and payload were not changed.

Common claims

Some claim names are standard, and you will see them in almost every token.

ClaimMeaning
subSubject: who the token is about, often a user ID
issIssuer: who created the token
audAudience: who the token is meant for
expExpiry time, as a Unix timestamp in seconds
nbfNot before: the token is invalid until this time
iatIssued at: when the token was created

How to decode a JWT

Paste the token into a JWT decoder and it splits the three parts, converts the first two from Base64URL and shows the JSON. You can do it by hand too: take the part before the first dot and decode it as Base64.

As an example, this header and payload are the first two parts of a well-known sample token:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
→ {"alg":"HS256","typ":"JWT"}

eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ
→ {"sub":"1234567890","name":"John Doe","iat":1516239022}

How a JWT is used

You sign in, and the server checks your password and replies with a token. Your app then sends the token with every later request, usually in an Authorization header written as Bearer followed by the token. The server checks the signature and the expiry, and if both are good it knows who is asking without looking anything up in a database. That is why tokens are popular for APIs and for single sign-on.

How the signature works

With HS256 the same secret is used to sign and to check, so only systems that share the secret can verify a token. With RS256 a private key signs and a public key checks, so anyone can verify a token but only the issuer can create one. Either way, changing a single character of the header or the payload makes the signature fail.

Reading the dates

The exp, nbf and iat claims are Unix timestamps: seconds since 1 January 1970 in UTC. In the example, iat of 1516239022 is 18 January 2018 at 01:30:22 UTC. Paste a timestamp into a timestamp converter to see it as a date, and to check whether a token has expired.

Decoding is not verifying

Anyone who has a token can decode it, because Base64URL is an encoding, not encryption. So never put a password or any other secret in a payload. Decoding also does not prove the token is genuine: only a server that holds the key can check the signature. A tool that only decodes will happily display a token that someone forged.

Frequently asked questions

Is a JWT encrypted?
A normal JWT is signed, not encrypted. The payload is readable by anyone who has the token, so it should never contain secrets. There is an encrypted form, but it is much less common.
Is it safe to paste a JWT into an online decoder?
Only if the decoder runs in your browser and never sends the token anywhere. Even then, avoid pasting live production tokens into any site you cannot inspect.
Why does my token say it is expired?
The exp claim is earlier than the current time. Convert exp to a date to see by how much, and check that the clocks on the issuing and receiving systems agree.

Try the tools