What Is a JWT?
A JSON Web Token (JWT, pronounced "jot") is a compact, URL-safe token format defined in RFC 7519. It is the standard token format for stateless authentication in web applications and APIs.
A JWT looks like this:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
The dots divide it into three Base64URL-encoded parts.
The Three Parts
Header. A JSON object identifying the token type and signing algorithm:
{
"alg": "HS256",
"typ": "JWT"
}
Payload. A JSON object containing claims — statements about the subject and additional metadata:
{
"sub": "1234567890",
"name": "John Doe",
"iat": 1516239022
}
Signature. Created by signing the encoded header and payload with a secret or private key. For HS256: HMACSHA256(base64url(header) + "." + base64url(payload), secret).
Standard Claims
The JWT spec defines a set of registered claim names (all optional but conventionally used):
| Claim | Name | Meaning |
|---|---|---|
iss |
Issuer | Who issued the token |
sub |
Subject | User or entity the token is about |
aud |
Audience | Intended recipient(s) |
exp |
Expiration | Unix timestamp after which the token is invalid |
nbf |
Not Before | Unix timestamp before which the token is invalid |
iat |
Issued At | Unix timestamp when the token was issued |
jti |
JWT ID | Unique identifier for the token |
How JWT Authentication Works
- User logs in with credentials
- Server verifies credentials and issues a signed JWT
- Client stores the JWT (typically in memory or
localStorage) - Client sends the JWT in the
Authorization: Bearer <token>header on subsequent requests - Server verifies the JWT signature — no database lookup needed
- Server reads claims from the payload to identify the user and their permissions
Security Mistakes to Avoid
Algorithm confusion attacks. Never accept "alg": "none" — some early JWT libraries accepted unsigned tokens. Always explicitly verify the algorithm on the server side.
Storing JWTs in localStorage. localStorage is accessible to any JavaScript on the page. XSS vulnerabilities can steal tokens. Consider httpOnly cookies for session tokens.
Long-lived tokens without refresh. Short expiry (exp) times limit damage from token theft. Use refresh tokens for long sessions.
Not validating exp, iss, aud. Verify all relevant claims on the server — an expired token or a token issued for a different audience should be rejected.
Sensitive data in payload. The payload is Base64URL-encoded, not encrypted. Anyone with the token can read the claims. Never put passwords, private keys, or sensitive PII in a JWT payload without additional encryption (JWE).
Try It
The JWT Decoder on Syntaxly decodes the header and payload of any JWT and displays the claims in a readable format. It also shows the expiry status. Nothing is sent to a server.