1. Introduction
A JWT (JSON Web Token) is a compact, URL-safe token format used for securely transmitting information between parties. It’s widely used in modern applications for authentication and authorization.
A JWT is composed of three parts:
<Header>.<Payload>.<Signature>
All three parts are Base64URL-encoded strings, separated by periods (.).
While the signature part is cryptographically secure and not human-readable, the header and payload can be easily decoded and viewed — even without a secret key.
2. JWT Structure
Example JWT:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9 . eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ . SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
Let’s break it down:
1. Header (Visible)
Encodes metadata about the JWT — such as the algorithm used to sign it.
Decoded:
{
"alg": "HS256",
"typ": "JWT"
}
Readable? Yes — it is Base64URL-decoded and shows:
alg: algorithm used for signing (e.g.,HS256,RS256)typ: token type (typically"JWT")
2. Payload (Visible)
This is the most important part — it contains the claims (information) about the user and token.
Decoded:
{
"sub": "1234567890",
"name": "John Doe",
"iat": 1516239022
}
Readable? Yes — easily viewable by anyone who has the JWT.
Types of Information Found in the Payload:
a. Standard (Registered) Claims
These are well-known and defined in the JWT specification.
| Claim | Description |
|---|---|
iss | Issuer — who created the token |
sub | Subject — whom the token is about |
aud | Audience — intended recipient(s) |
exp | Expiration time — when the token expires |
nbf | Not before — when the token becomes valid |
iat | Issued at — when the token was issued |
jti | JWT ID — unique identifier for the token |
{
"iss": "https://auth.example.com",
"sub": "user123",
"exp": 1723459200,
"iat": 1723455600
}
b. Public Claims
These are custom claims that use globally unique names (often using a URI) to avoid collision.
{
"https://example.com/user_role": "admin"
}
c. Private Claims
These are custom claims defined between the issuer and consumer.
{
"user_id": "abc123",
"preferred_language": "en",
"role": "admin"
}
Note: All of these are readable in plain text once Base64URL-decoded.
3. Signature (Not Readable, Not Modifiable)
This part ensures the integrity of the token. It’s generated using the header, payload, and a secret key or private key.
Readable? No — it’s not human-readable or decodable.
Purpose? Verifies that:
- the token wasn’t tampered with,
- the token was actually issued by a trusted party.
Example:
SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
3. Which Information Can Be Seen by Anyone?
Anyone who has the JWT string can decode and see:
- The Header
- The Payload (Claims)
They cannot:
- Verify the authenticity of the signature without the secret/private key
- Modify the payload without invalidating the signature
But they can still read all claims — so no sensitive data (like passwords, credit card numbers) should ever be put in the payload.
4. How to View a JWT?
You can decode a JWT using:
- Online Tools:
https://jwt.io — paste a JWT and see its contents. - Command Line (Linux/Unix/macOS):
# Decode header echo 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9' | base64 --decode # Decode payload echo 'eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ' | base64 --decode
- In Code:
// JavaScript (no validation)
const parts = jwt.split(".");
const header = JSON.parse(atob(parts[0]));
const payload = JSON.parse(atob(parts[1]));
console.log(header, payload);
5. Important Security Warning
Just Because It’s Encoded Doesn’t Mean It’s Encrypted
JWTs use Base64URL encoding, not encryption. So:
- They are NOT secure by themselves.
- Never put private information in the JWT payload.
- Anyone who gets the JWT can see its contents.
Only the Signature Is Secure
The signature proves:
- The token is genuine.
- It was not tampered with.
But it doesn’t hide or protect the contents.
6. Best Practices
- Always validate the JWT on the server.
- Always check:
exp(expiration)aud(audience)iss(issuer)
- Never trust information just because it’s in the token.
- Never store sensitive information (passwords, bank account, etc.) in the payload.
- If using JWTs in browser storage (like localStorage), ensure XSS protection.
7. Summary
| Component | Contains | Readable? | Secure? |
|---|---|---|---|
| Header | Metadata (e.g., alg, typ) | Yes | No |
| Payload | Claims (user info, exp, etc.) | Yes | No |
| Signature | Digital signature | No | Yes |
JWTs are compact and efficient, but not secure for confidential information unless combined with encryption (e.g., via JWE).
