JWT Parser
Parse JSON Web Tokens (JWT) into their three components: header, payload, and signature. Understand the structure and contents of any JWT instantly with our free online parser. All processing happens locally in your browser for complete privacy.
Understanding JWT Structure
A JWT consists of three Base64URL-encoded parts separated by dots:
``
xxxxx.yyyyy.zzzzz
header.payload.signature
`
| Component | Contents | Purpose |
|---|---|---|
| Header | Algorithm (alg), token type (typ) | Tells how to verify the signature |
| Payload | Claims (iss, sub, exp, iat, custom) | The actual data/claims |
| Signature | HMAC or RSA signature | Proves the token wasn't tampered with |
Example JWT Decoded
Token:
`
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
`
Parsed Header:
`json
{
"alg": "HS256",
"typ": "JWT"
}
`
Parsed Payload:
`json
{
"sub": "1234567890",
"name": "John Doe",
"iat": 1516239022
}
`
JWT Parser Implementation
`javascript
function parseJWT(token) {
const parts = token.split('.');
if (parts.length !== 3) {
throw new Error('Invalid JWT format - must have 3 parts');
}
// Base64URL decode helper
const decode = (str) => {
const base64 = str.replace(/-/g, '+').replace(/_/g, '/');
const padding = '='.repeat((4 - base64.length % 4) % 4);
return JSON.parse(atob(base64 + padding));
};
return {
header: decode(parts[0]),
payload: decode(parts[1]),
signature: parts[2]
};
}
// Node.js version
function parseJWTNode(token) {
const parts = token.split('.');
return {
header: JSON.parse(Buffer.from(parts[0], 'base64url').toString()),
payload: JSON.parse(Buffer.from(parts[1], 'base64url').toString()),
signature: parts[2]
};
}
`
Standard JWT Claims Reference
| Claim | Full Name | Description | Example |
|---|---|---|---|
| iss | Issuer | Who created the token | "auth.example.com" |
| sub | Subject | User/entity identifier | "user_123" |
| aud | Audience | Intended recipients | "api.example.com" |
| exp | Expiration | When token expires | 1735689600 |
| iat | Issued At | When token was created | 1735686000 |
| nbf | Not Before | Token not valid before | 1735686000 |
| jti | JWT ID | Unique token identifier | "abc123" |
Where JWTs Are Used
Authentication: Login sessions and user identity- OAuth 2.0: Access tokens and ID tokens
- API Authorization: Bearer tokens in HTTP headers
- Single Sign-On (SSO): Sharing identity across services
- Microservices: Service-to-service authentication
Security Notes
- Parsing ≠ Verification: Anyone can parse a JWT; verification requires the secret key
- Not Encrypted: JWT contents are readable by anyone with the token
- Check Expiration: Always verify exp claim before trusting a token
- Validate Issuer: Ensure iss matches your expected authentication server
The Attacks a Verifier Must Stop
alg: none. A token declaring no algorithm with an empty signature. A library that
trusts the header's alg will accept it as valid. Always specify the expected algorithm
when verifying rather than reading it from the token.
Algorithm confusion. A token signed with HMAC using the server's *public* RSA key as the
secret. If the verifier picks the algorithm from the header, an RS256 verifier can be tricked
into running HS256 with a key the attacker already has.
Weak secrets. HS256 with a short or dictionary secret is brute-forceable offline from a
single captured token. Use at least 256 bits of real entropy.
No expiry check. exp is a claim, not an enforcement. A library that decodes without
verifying, or code that reads claims from a decoded-but-unverified token, accepts expired and
forged tokens alike.
`javascript
// Specify the algorithm; never trust the header's
jwt.verify(token, secret, { algorithms: ['HS256'] });
`
Anyone Can Read the Payload
A JWT is signed, not encrypted. The payload is base64url — readable by anyone holding the
token, including the browser it is stored in. Never put anything in it you would not print
on a postcard: no passwords, no PII beyond an identifier, no internal keys.
Revocation Is the Hard Part
A signed token is valid until it expires, and there is no way to withdraw one. Options:
| Approach | Cost |
|---|---|
| Short expiry (5–15 min) plus refresh tokens | Standard; adds a refresh endpoint |
| A denylist of revoked JTIs | Reintroduces the state JWTs were meant to avoid |
| Rotate the signing key | Revokes every token at once |
| Version claim checked against the user record | A database read per request |
If you need immediate revocation for every session, a server-side session is a simpler and
more honest choice than a JWT.Where to Store One
| Location | XSS-safe | CSRF-safe |
|---|---|---|
localStorage | No | Yes |
| sessionStorage` | No | Yes |
| Cookie (HttpOnly, Secure, SameSite) | Yes | Yes, with SameSite |
| In-memory | Yes | Yes |
An HttpOnly cookie is the safest default. Any token reachable from JavaScript is reachable by
any script that gets injected.