If you work with any modern authentication system — OAuth, Auth0, Firebase, or your own backend API — you have almost certainly encountered a JWT. They appear in HTTP headers, local storage, and API responses, but what exactly is inside one, and how do you read it safely?
What is a JWT?
JWT stands for JSON Web Token. It is a compact, URL-safe string used to securely transmit information between two parties. The information is encoded — not encrypted — so it can be read by anyone who has the token.
JWTs are most commonly used for authentication. After a user logs in, the server issues a JWT. The client stores it and sends it with every subsequent request. The server verifies the token's signature to confirm it is legitimate — without needing to query a database on every request.
The structure of a JWT
A JWT is three Base64URL-encoded strings joined by dots:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c Header.Payload.Signature
Part 1 — Header
The header describes the token type and the algorithm used to sign it:
{
"alg": "HS256", // signing algorithm
"typ": "JWT" // token type
}Part 2 — Payload
The payload contains the actual data — called claims. These are statements about the user and any additional metadata:
{
"sub": "1234567890", // subject (usually user ID)
"name": "John Doe", // custom claim
"email": "[email protected]",
"role": "admin",
"iat": 1516239022, // issued at (Unix timestamp)
"exp": 1516242622 // expiry (Unix timestamp)
}Standard claims include:
- sub — subject, usually the user's ID
- iat — issued at, when the token was created
- exp — expiry time, after which the token is invalid
- iss — issuer, who created the token
- aud — audience, who the token is intended for
Part 3 — Signature
The signature is created by the server using the header, the payload, and a secret key:
HMACSHA256( base64UrlEncode(header) + "." + base64UrlEncode(payload), secret )
The signature is what makes JWTs trustworthy. Anyone can read the header and payload, but only the server that holds the secret key can produce a valid signature. If someone tampers with the payload, the signature will no longer match and the token will be rejected.
Important: JWTs are encoded, not encrypted. Anyone who has the token can read the header and payload. Never store sensitive data like passwords or payment details in a JWT payload.
How to decode a JWT
Decoding a JWT means reading the header and payload — it requires no secret key. You are simply reversing the Base64URL encoding.
In JavaScript:
function decodeJWT(token) { const parts = token.split('.'); const header = JSON.parse(atob(parts[0])); const payload = JSON.parse(atob(parts[1])); return { header, payload }; } // Usage const decoded = decodeJWT(myToken); console.log(decoded.payload.email); // "[email protected]"
Note: atob() decodes standard Base64. JWT uses Base64URL which replaces + with - and / with _. For production use, handle this substitution or use a proper JWT library.
Verifying vs decoding
Decoding and verifying are two different things:
- Decoding — reading the payload contents. Anyone can do this. No secret needed.
- Verifying — confirming the signature is valid and the token has not been tampered with. Requires the secret key or public key. This should only happen on the server.
When you use a JWT decoder tool to inspect a token, you are decoding — not verifying. The token's claims may be readable but that does not mean the token is legitimate.
Is it safe to paste a JWT into a decoder tool?
It depends on what the token contains and which tool you use. Two things to check:
- Does the tool run in the browser? If yes, your token never leaves your device. It is safe to use.
- Does the tool send data to a server? If yes, you are exposing the token to a third party. Avoid this for production tokens.
Our JWT Decoder runs entirely in your browser. The token you paste is never sent anywhere — it is decoded using JavaScript on your own device.
Decode a JWT token instantly
Paste any JWT and see the decoded header, payload, and expiry time. Runs entirely in your browser — nothing is ever sent to a server.
Open JWT Decoder →