If you’ve ever logged into a web app and stayed logged in without hitting “remember me,” chances are a JWT was at work behind the scenes.
JSON Web Tokens (JWTs) have quietly become the backbone of modern authentication systems. They power APIs, mobile apps, microservices, and even decentralized platforms. But what exactly are they, how do they work, and when should (or shouldn’t) you use them?
The strengths are real, and so are the pitfalls.
What is a JWT?
A JWT (JSON Web Token) is a compact, URL-safe token that represents claims securely between two parties, typically a client and a server.
It’s made up of three parts, separated by dots (.):
xxxxx.yyyyy.zzzzz
The Three Parts
- The header describes the token type and signing algorithm.
{
"alg": "HS256",
"typ": "JWT"
}- The payload contains the claims, meaning the data about the user or session.
{
"sub": "1234567890",
"name": "Mahmudul Alam",
"admin": true,
"exp": 1734283200
}- The signature verifies that the token hasn’t been tampered with.
HMACSHA256(
base64UrlEncode(header) + "." + base64UrlEncode(payload),
secret
)When encoded, it looks like this (shortened for sanity):
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6Ik1haG11ZHVsIEF
sYW0iLCJhZG1pbiI6dHJ1ZX0.
TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ
Compact, self-contained, and readable.
How JWT Works (Step-by-Step)
Imagine you’re logging into a web app. Here’s the flow:
- Client sends credentials (username/password) to the server.
- Server verifies and issues a JWT signed with a secret key.
- Client stores the token (often in
localStorageor anHTTP-only cookie). - For each subsequent request, the client attaches the JWT in the
Authorizationheader:
Authorization: Bearer <token>
- The server validates the token’s signature and expiration time (no database lookup needed).
- If valid, the request proceeds as the authenticated user.
This stateless model scales beautifully: no session store required.
Why JWT Became So Popular
JWTs work across distributed systems and microservices without centralized session storage, and they’re compact enough to fit easily in HTTP headers or URLs. Each token is self-contained: it carries all the user information (claims) needed for authorization. They work in browsers, mobile apps, and APIs, and they’re supported across Node.js, Python, Go, Java, Rust, and more.
Common Misconceptions (and Mistakes)
JWT ≠ Encryption
JWTs are signed, not encrypted (by default). That means:
- Anyone can decode and read the payload.
- But they cannot modify it without invalidating the signature.
If you need confidentiality, use JWE (JSON Web Encryption).
Long-lived tokens are dangerous
JWTs don’t have a built-in revoke mechanism. If you issue tokens that last too long, they can be stolen and abused.
The fix is to use short-lived access tokens (e.g., 15 minutes) and refresh tokens to reissue them safely.
Don’t store JWT in localStorage
While it’s tempting, it exposes you to XSS attacks. Instead, prefer HTTP-only cookies, which are not accessible via JavaScript.
When to Use JWT — and When Not To
Great Use Cases
- Single-page apps (SPA) or mobile APIs
- Microservices that need stateless auth
- Federated identity systems (OAuth 2.0 / OpenID Connect)
- Server-to-server authentication
Avoid JWT if:
- You need to invalidate sessions immediately (use traditional sessions)
- You’re building a simple monolithic app
- You don’t need to scale horizontally
Signature Algorithms
Common signing algorithms include:
| Algorithm | Type | Description |
|---|---|---|
| HS256 | Symmetric | HMAC + SHA256 using shared secret key |
| RS256 | Asymmetric | RSA + SHA256 using private/public key pair |
| ES256 | Asymmetric | Elliptic Curve + SHA256 (lightweight, secure) |
Prefer RS256 or ES256 for stronger key management.
Example in Node.js (with jsonwebtoken)
import jwt from 'jsonwebtoken';
const secret = 'supersecretkey';
// Sign a token
const token = jwt.sign({ userId: 42, role: 'admin' }, secret, { expiresIn: '15m' });
// Verify a token
try {
const decoded = jwt.verify(token, secret);
console.log(decoded);
} catch (err) {
console.error('Invalid or expired token');
}JWT vs Session Cookies: Quick Comparison
| Feature | JWT | Session Cookies |
|---|---|---|
| Storage | Client-side | Server-side |
| Scalability | Excellent | Limited |
| Revocation | Hard | Easy |
| Security | Depends on implementation | Easier to secure |
| Use Case | APIs, SPAs, mobile apps | Classic web apps |
When JWT Is Worth It
JWTs are incredibly powerful, but like any power tool, they demand responsible use.
Used correctly, they offer scalable, stateless, cross-platform authentication. Used carelessly, they can open serious security vulnerabilities.
Rule of thumb: If your app talks to multiple services or clients, JWT is your friend. If it’s a simple web app, traditional sessions may still be your best bet.
