JWT Explained: What Is Inside a JSON Web Token
If you have worked with a login system, an API or single sign-on, you have met JSON Web Tokens — long strings like eyJhbGciOi... that travel in an Authorization header. They look encrypted, but they are not, and misunderstanding that is behind many security bugs.
This guide explains what a JWT contains, how to read one, what the common claims mean, and the rules for using JWTs safely.
Three parts separated by dots
A JWT has three parts: header.payload.signature. Each part is Base64URL-encoded — a URL-safe version of Base64 — so the whole token can be sent in headers and URLs without escaping.
The header is a small JSON object saying which algorithm signed the token, for example {"alg":"HS256","typ":"JWT"}. The payload is a JSON object with the "claims" — statements about the user and the token. The signature is calculated from the header and payload using a secret key or a private key.
Anyone can read a JWT
Base64URL is an encoding, not encryption. Anyone who has the token can decode the header and payload and read every claim — that is exactly what a JWT decoder does. Never put passwords, secrets or sensitive personal data in a JWT payload.
What the signature provides is integrity: if someone changes even one character of the payload, the signature no longer matches, and a server that verifies the signature will reject the token.
Common claims and what they mean
iss (issuer) is who created the token; sub (subject) is usually the user ID; aud (audience) is which service the token is meant for. exp (expiration time) is when the token stops being valid, nbf (not before) is when it starts being valid, and iat (issued at) is when it was created. jti is a unique ID for the token.
The time claims are Unix timestamps in seconds, not milliseconds — a frequent source of bugs when JavaScript code compares them with Date.now(), which returns milliseconds.
How to inspect a token
When debugging a login or API problem, decode the token to check what it really contains:
- Copy the token (without the "Bearer " prefix).
- Paste it into JWT Decoder — decoding happens in your browser, so the token is not sent anywhere.
- Check the algorithm, the issuer and audience, and whether exp is in the past.
- Compare the claims with what your API expects, for example the user ID or roles.
Rules for using JWTs safely
Always verify the signature on the server before trusting any claim, and check exp, nbf, iss and aud. Decoding alone proves nothing — anyone can create a token with any payload.
Pin the accepted algorithm in your verification code, and never accept "alg": "none". Keep tokens short-lived and use refresh tokens for long sessions, because a stolen JWT is valid until it expires.
Treat tokens like passwords: do not paste production tokens into tools that send data to a server, and do not log them.
Frequently asked questions
Is a JWT encrypted?
A normal (signed) JWT is not encrypted — its payload is readable by anyone. Encrypted tokens (JWE) exist, but they look different and are less common.
Can I verify a JWT signature in a decoder?
Only if you provide the secret or public key. A decoder that only reads the token, like FilesSwift JWT Decoder, does not verify it.
Why does my token say expired when it was just issued?
Check the clocks of the server and the client, and check whether exp was written in milliseconds instead of seconds.
What is the difference between HS256 and RS256?
HS256 uses one shared secret for signing and verifying. RS256 uses a private key to sign and a public key to verify, so services can verify tokens without being able to create them.