If you have worked with any modern web application that has user authentication, you have almost certainly encountered JWT tokens. They appear in HTTP headers, cookies, and localStorage โ but what exactly are they, how do they work, and why do so many APIs use them? This guide explains everything.
What is a JWT?
JWT stands for JSON Web Token. It is an open standard (RFC 7519) that defines a compact, self-contained way for securely transmitting information between two parties as a JSON object. The key word is self-contained โ a JWT carries all the information needed to identify a user without the server needing to look anything up in a database.
A JWT looks like this:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJ1c2VyXzEyMyIsIm5hbWUiOiJBcmp1biBTaGFybWEiLCJpYXQiOjE3MzAwMDAwMDB9.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
Notice the two dots? A JWT is always made of exactly three parts separated by dots:
- Header โ algorithm and token type
- Payload โ the actual claims (user data)
- Signature โ verifies the token has not been tampered with
Part 1: The Header
The header contains two fields โ the signing algorithm and the token type. It is Base64Url encoded (not encrypted):
// Decoded header
{
"alg": "HS256",
"typ": "JWT"
}
Common algorithms include HS256 (HMAC SHA-256), RS256 (RSA SHA-256), and ES256 (ECDSA). HS256 uses a shared secret key. RS256 uses a public/private key pair โ much more secure for distributed systems.
Part 2: The Payload (Claims)
The payload contains the data you want to transmit. Each piece of data is called a claim. JWT defines several standard (registered) claims:
subโ Subject (usually the user ID)issโ Issuer (who created the token)expโ Expiration time (Unix timestamp)iatโ Issued at (when the token was created)audโ Audience (intended recipient)nbfโ Not before (token is invalid before this time)
// Decoded payload
{
"sub": "user_123",
"name": "Arjun Sharma",
"email": "arjun@example.com",
"role": "admin",
"iat": 1730000000,
"exp": 1730086400
}
Important: The payload is only Base64Url encoded โ it is NOT encrypted. Anyone who has the token can decode and read the payload. Never store sensitive data like passwords in a JWT payload.
Part 3: The Signature
The signature is what makes JWT secure. It is created by taking the encoded header, the encoded payload, a secret key, and running it through the specified algorithm:
HMACSHA256(
base64UrlEncode(header) + "." + base64UrlEncode(payload),
secretKey
)
If anyone modifies the payload โ even changing a single character โ the signature will no longer match and the server will reject the token. This is how the server knows the token is authentic and unmodified.
How JWT Authentication Works
Here is the complete JWT authentication flow:
- Login: User sends username and password to the server
- Token creation: Server verifies credentials, creates a JWT signed with its secret key, and sends it back to the client
- Storage: Client stores the JWT (in localStorage, a cookie, or memory)
- API requests: Client sends the JWT in the
Authorizationheader on every subsequent request:Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9... - Verification: Server receives the request, verifies the signature, checks the expiry, and grants access if valid โ without querying the database
JWT vs Session-Based Authentication
Traditional session authentication stores session data on the server (in memory or a database). With JWT, all the data is in the token itself โ the server is stateless.
| Aspect | JWT | Sessions |
|---|---|---|
| Storage | Client-side | Server-side |
| Scalability | Excellent (stateless) | Requires shared session store |
| Revocation | Difficult (until expiry) | Easy (delete from store) |
| Size | Larger (sent every request) | Small (just a session ID) |
JWT Security Best Practices
- Use short expiry times โ 15 minutes to 1 hour for access tokens. Use refresh tokens for longer sessions.
- Use RS256 instead of HS256 for distributed systems โ different services can verify without knowing the private key.
- Never store JWTs in localStorage for sensitive applications โ they are vulnerable to XSS attacks. Use HttpOnly cookies instead.
- Always validate the signature โ never trust the payload without verifying the signature first.
- Validate the expiry (
exp) โ always check that the token has not expired. - Never put sensitive data in the payload โ it is only encoded, not encrypted. Anyone can decode it.
Decoding a JWT
You can decode any JWT (remember, it is not encrypted) using our free JWT Decoder tool. Simply paste your token and see the header, payload and expiry status immediately โ no login required, and your token never leaves your browser.
Summary
JWT is a compact, self-contained token format that enables stateless authentication. It consists of a Base64Url-encoded header and payload, plus a cryptographic signature. Understanding JWT is essential for any developer working with modern REST APIs, microservices, or single-page applications.