JSON Web Tokens (JWTs) are the de-facto standard for API authentication in 2026. If you have ever logged into a web app, you have a JWT. But what is actually inside that eyJ... string?
The three parts
A JWT is three Base64URL-encoded JSON objects, joined by dots:
header.payload.signature
For example:
eyJhbG...VCJ9 .eyJzdW...IyfQ .SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
Each part is independently Base64URL-decodable. There is no encryption — the payload is plaintext, readable by anyone with the token.
Header
The header describes the algorithm and token type:
{
"alg": "HS256",
"typ": "JWT"
}
Common algorithms:
- HS256 / HS384 / HS512 — HMAC with a shared secret
- RS256 / RS384 / RS512 — RSA signature (asymmetric)
- ES256 / ES384 / ES512 — ECDSA (asymmetric, more compact)
- EdDSA — Ed25519 (modern, fast, secure)
- none — no signature. Never use this in production.
Payload
The payload contains the claims — statements about the user and the token:
{
"sub": "1234567890",
"name": "John Doe",
"iat": 1516239022,
"exp": 1516242622
}
Standard claims:
- iss — issuer (who created the token)
- sub — subject (who the token is about)
- aud — audience (who the token is intended for)
- exp — expiration time (seconds since epoch)
- nbf — not before (token invalid until this time)
- iat — issued at
- jti — unique token ID (for revocation lists)
You can also add custom claims (like name, role, email) for application-specific data.
Signature
The signature is computed over the first two parts:
HMAC-SHA256( base64url(header) + "." + base64url(payload), secret )
For HS256, the server uses a shared secret. For RS256/ES256, the server uses a private key. Anyone with the public key can verify the signature, but only the holder of the private key can create it.
What JWT is not
- Not encrypted — the payload is readable by anyone. If you need encryption, use JWE.
- Not a session — JWTs are stateless. Revocation requires additional infrastructure (deny lists, short expirations, refresh tokens).
- Not invulnerable —
alg: none, weak secrets, and algorithm confusion attacks have all been exploited in the wild.
How to verify
On every request:
- Split the token on dots.
- Base64URL-decode the header and payload.
- Check the algorithm is one you expect (do not trust the header).
- Verify the signature using the appropriate key.
- Check
exp,nbf,iss,aud. - Use the claims to authorize the request.
Inspect any JWT with our JWT Decoder.
Frequently Asked Questions
Q: Is JWT encrypted? Can I read the payload?
No. JWTs are not encrypted. The payload is Base64URL-encoded, not encrypted. Anyone with the token can decode and read it. For sensitive data, use JWE (Encryption) instead. See the JWT RFC 7519 for the full spec.
Q: What's the difference between JWT and JWS?
JWT (JSON Web Token) is the high-level concept. JWS (JSON Web Signature) is the specific mechanism used for signing. Most JWTs in API auth are technically JWS tokens.
Q: How long should a JWT live?
Access tokens should live 15-60 minutes. Refresh tokens can live days to weeks. Longer is riskier —if a JWT leaks, the attacker has access until it expires.