JWT (JSON Web Token) is a compact, URL-safe way to represent claims between two parties. It is the most widely used token format for API authentication — used by OAuth 2.0, OpenID Connect, and most modern REST APIs.
JWT Structure
A JWT consists of three Base64URL-encoded parts separated by dots: header.payload.signature
TEXT
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkFsaWNlIiwiaWF0IjoxNjk5MDAwMDAwfQ
.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5cJSON
// Header (algorithm & type)
{
"alg": "HS256",
"typ": "JWT"
}
// Payload (claims)
{
"sub": "1234567890", // Subject (user ID)
"name": "Alice",
"iat": 1699000000, // Issued At (Unix timestamp)
"exp": 1699086400 // Expiry (24 hours later)
}Standard Claims (Registered)
| Claim | Full Name | Description |
|---|---|---|
iss | Issuer | Who issued the token (e.g., "auth.myapp.com") |
sub | Subject | User the token refers to (user ID) |
aud | Audience | Who should accept this token |
exp | Expiration | Unix timestamp when token expires |
iat | Issued At | Unix timestamp when token was issued |
jti | JWT ID | Unique ID for this specific token (prevents replay) |
How JWT Authentication Works
- User logs in with email + password
- Server validates credentials, creates JWT, signs it with a secret key
- Server sends JWT back to the client
- Client stores JWT (localStorage, cookie, or memory)
- On every API request, client sends JWT in
Authorization: Bearerheader - Server validates JWT signature — no database lookup needed
- If valid and not expired, server processes the request
Signing Algorithms
| Algorithm | Type | Use Case |
|---|---|---|
| HS256 | HMAC-SHA256 (symmetric) | Same secret for signing & verifying. Single-service apps. |
| HS384 | HMAC-SHA384 (symmetric) | Stronger HMAC. Same use case as HS256. |
| RS256 | RSA-SHA256 (asymmetric) | Private key signs, public key verifies. Microservices. |
| ES256 | ECDSA-SHA256 (asymmetric) | Smaller key size than RSA. High-security APIs. |
Common JWT Vulnerabilities
Algorithm Confusion Attack — never trust the
alg field in the header. Always specify the expected algorithm on the server side. Attackers have set "alg": "none" to bypass signature verification in vulnerable implementations.- Storing JWT in localStorage — vulnerable to XSS attacks. Prefer HttpOnly cookies.
- No expiry (
exp) — tokens that never expire are permanent security holes. - Weak secrets —
secret,123456can be brute-forced. Use 256-bit random secrets. - No token blacklisting — after logout, old tokens still work until expiry.
- Sensitive data in payload — payload is Base64 encoded, not encrypted. Anyone can decode it.
Best Practices
- Set short expiry (15 min access tokens + 7 day refresh tokens)
- Use RS256 or ES256 for distributed systems
- Store in HttpOnly, Secure, SameSite=Strict cookies
- Include
jticlaim and maintain a token revocation list - Rotate signing keys periodically
- Always validate
issandaudclaims
Use DevToolkit's JWT Inspector to instantly decode any JWT token — see expiry countdown, all claims, and security analysis without sending data to any server.