JWT
JSON Web Token reference: token structure, header fields, standard claims, signing algorithms, security best practices, and common errors.
A JSON Web Token (JWT) is a compact, URL-safe token used to represent claims between two parties. It is defined in RFC 7519 and widely used for stateless authentication and API authorization.
Token Structure
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjMiLCJuYW1lIjoiQWxpY2UiLCJpYXQiOjE3MzAwMDAwMDB9.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
Each part is Base64URL-encoded and separated by dots. The payload is not encrypted — never store secrets in it.
Header
{
"alg": "HS256",
"typ": "JWT"
}"alg"Signing algorithm (HS256, RS256, ES256…). Use "none" only for unsecured tokens — almost always a security risk."typ"Token type. Always "JWT" for standard tokens."kid"Key ID. Optional hint for key selection when multiple keys are used.Standard Claims (Payload)
| Claim | Full name | Description | Type |
|---|---|---|---|
| iss | Issuer | Who issued the token (e.g., your auth server URL) | string |
| sub | Subject | Who the token is about (usually a user ID) | string |
| aud | Audience | Who the token is intended for (API or service identifier) | string|string[] |
| exp | Expiration | Unix timestamp after which the token is invalid | number (NumericDate) |
| nbf | Not Before | Unix timestamp before which the token must not be accepted | number (NumericDate) |
| iat | Issued At | Unix timestamp when the token was issued | number (NumericDate) |
| jti | JWT ID | Unique identifier for the token (used to prevent replay) | string |
All standard claims are optional but highly recommended. exp is especially critical for security.
Signing Algorithms
| Algorithm | Type | Key | Use when |
|---|---|---|---|
| HS256 | HMAC | Shared secret (same key to sign & verify) | Single-service auth; keep secret safe |
| HS384 | HMAC | Shared secret | Same as HS256 but stronger hash |
| HS512 | HMAC | Shared secret | Strongest HMAC option |
| RS256 | RSA | Private key signs, public key verifies | Multi-service / distributed auth (OAuth, OIDC) |
| ES256 | ECDSA | Private key signs, public key verifies | Same as RS256 but shorter key & faster |
| PS256 | RSA-PSS | Private key signs, public key verifies | FIPS-compliant RSA alternative |
| none | — | None | Unsecured token — reject unless explicitly expected |
Security Best Practices
Always validate exp
Reject tokens past their expiration timestamp. Short-lived tokens (15 min – 1 h) reduce exposure.
Validate iss and aud
Ensure the token was issued by your auth server and is intended for your service.
Use asymmetric keys for distributed systems
RS256/ES256 let services verify tokens without sharing a secret.
Store tokens securely
Use HttpOnly cookies for web apps. Avoid localStorage for sensitive tokens.
Never put secrets in the payload
The payload is Base64URL-encoded, not encrypted. Anyone with the token can read it.
Never accept "alg: none"
Attackers can forge tokens by stripping the signature and setting alg to "none".
Don't use JWT for sessions (usually)
JWTs can't be revoked before expiry. Use server-side sessions for admin revocation.
Common Errors
TokenExpiredErrorexp timestamp is in the past. Issue a new token via refresh flow.InvalidSignatureErrorWrong secret/key used to verify, or token was tampered with.NotBeforeErrornbf timestamp is in the future — token not yet valid.JsonWebTokenErrorMalformed token: not 3 dot-separated Base64URL segments.InvalidAudienceErroraud claim doesn't match what the server expected.InvalidIssuerErroriss claim doesn't match the expected issuer.Decode and inspect JWTs with our JWT Decoder →
Paste any token and see the decoded header, payload, and claims.