What is JWT (JSON Web Token)?
JSON Web Token (JWT) is an open standard (RFC 7519) for securely transmitting information between parties as a JSON object. JWTs are compact, URL-safe tokens that contain claims about a user or entity, digitally signed to ensure authenticity and integrity.
Think of JWT like a digital passport - it contains your identity information, is issued by a trusted authority (your server), and can be verified by anyone who trusts that authority without needing to contact them again.
JWT Structure: The Three Parts
A JWT consists of three parts separated by dots (.):
- Header: Contains metadata about the token (type and signing algorithm)
- Payload: Contains the claims (user data and additional information)
- Signature: Ensures the token hasn't been tampered with
Example JWT: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
How JWT Authentication Works
- User Login: User sends credentials (username/password) to server
- Token Generation: Server validates credentials and generates a JWT containing user info
- Token Storage: Client stores the JWT (usually in localStorage or cookies)
- Authenticated Requests: Client includes JWT in Authorization header for subsequent requests
- Token Validation: Server validates the JWT signature and checks expiration
- Access Granted: If valid, server processes the request
JWT vs Session Cookies: Which to Choose?
| Feature | JWT | Session Cookies |
|---|---|---|
| Storage | Client-side (localStorage, cookies) | Server-side session store |
| Scalability | Excellent (stateless) | Requires session synchronization |
| Revocation | Difficult (requires blacklist) | Easy (delete session) |
| Size | Larger (contains data) | Smaller (just session ID) |
| CSRF Protection | Not needed (if stored properly) | Requires CSRF tokens |
Common JWT Claims Explained
- iss (Issuer): Who created and signed the token
- sub (Subject): Who the token is about (usually user ID)
- aud (Audience): Who the token is intended for
- exp (Expiration): When the token expires (Unix timestamp)
- iat (Issued At): When the token was created
- nbf (Not Before): Token is not valid before this time
- jti (JWT ID): Unique identifier for the token
You can also include custom claims like user roles, permissions, email, etc.
JWT Security Best Practices
- Use Strong Signing Algorithms: Use RS256 (RSA) or ES256 (ECDSA) for production. Avoid HS256 if possible.
- Keep Tokens Short-Lived: Set expiration time to 15-30 minutes for access tokens
- Use Refresh Tokens: Implement refresh tokens for longer sessions without compromising security
- Never Store Sensitive Data: JWTs can be decoded by anyone - don't include passwords or sensitive data
- Validate Everything: Always validate signature, expiration, issuer, and audience
- Use HTTPS Only: Always transmit JWTs over HTTPS to prevent interception
- Implement Token Revocation: Have a strategy for revoking tokens (blacklist or short expiration)
- Protect Secret Keys: Store signing keys securely (environment variables, key management systems)
Common JWT Vulnerabilities
1. None Algorithm Attack
Attackers set "alg" to "none" to bypass signature verification. Always validate the algorithm.
2. Weak Secret Keys
Using weak or default secrets makes tokens easy to forge. Use strong, randomly generated keys (256+ bits).
3. Algorithm Confusion
Attacker tricks server into using wrong algorithm (RS256 → HS256). Always specify expected algorithm.
4. Token Side-Jacking
JWTs stolen via XSS attacks. Store in httpOnly cookies instead of localStorage when possible.
5. Expired Token Acceptance
Not checking expiration allows old tokens to work forever. Always validate exp claim.
How to Decode and Validate JWT
Decoding a JWT is simple - it's just base64 encoded. However, validation requires checking the signature:
Manual Decoding (Education Only):
// Split the token
const [header, payload, signature] = token.split('.');
// Decode (note: this doesn't validate!)
const decodedHeader = JSON.parse(atob(header));
const decodedPayload = JSON.parse(atob(payload));
Proper Validation (Use Libraries!):
Always use established libraries for validation:
- Node.js: jsonwebtoken, jose
- Python: PyJWT, python-jose
- Java: java-jwt, jjwt
- PHP: firebase/php-jwt
- .NET: System.IdentityModel.Tokens.Jwt
JWT Use Cases
Perfect For:
- API Authentication: RESTful APIs and microservices
- Single Sign-On (SSO): Authenticate across multiple domains
- Mobile Apps: Stateless authentication for mobile clients
- Distributed Systems: No shared session storage needed
Not Ideal For:
- Traditional Web Apps: Session cookies may be simpler
- Real-time Revocation Needs: Hard to invalidate issued tokens
- Large Payloads: JWTs can become large with too much data
Try Our Free Tools
Explore ZapTools' collection of free online tools - no signup required!
View All Tools →