Every time you log into a web app and stay logged in as you navigate from page to page — some kind of token is quietly working behind the scenes.
In modern web development, that token is very often a JWT.
So, what is JWT exactly? If you have ever built or used a REST API, there is a good chance JWT came up. It is one of the most widely used authentication mechanisms on the web today — and understanding it is essential for any developer working with APIs, user authentication, or distributed systems.
In this guide, we break down what is JWT across 9 clear concepts. No security degree required. Real code examples included. By the end, you will know exactly how JWTs work, when to use them, and critically — what the common mistakes are.
Let’s go. 🚀
What is JWT? (Simple Definition)
What is JWT? JWT stands for JSON Web Token — pronounced “jot.” It is an open standard (RFC 7519) that defines a compact, self-contained way to securely transmit information between two parties as a JSON object.
Break that down piece by piece:
- Compact — Small enough to be sent in a URL, HTTP header, or cookie
- Self-contained — The token itself carries all the information needed — no database lookup required to verify it
- Secure — The information is digitally signed, so the receiver can verify it has not been tampered with
Here is what a real JWT looks like:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJ1c2VySWQiOjEyM30…
.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
Looks like random characters, right? It is actually three Base64-encoded sections separated by dots. Decode it and you find structured JSON data.
What is JWT used for?
- User authentication — proving who a user is after login
- API authorization — controlling what an authenticated user can access
- Information exchange — securely transmitting data between services
- Single Sign-On (SSO) — staying logged in across multiple related services
💡 Simple Analogy: What is JWT like in real life? Think of a JWT like a concert wristband. When you enter the venue, staff check your ticket and give you a wristband. After that, you show the wristband to enter different areas — VIP, backstage, general admission — without being checked against the ticket database every time. The wristband itself contains proof of your access level.
Why Was JWT Created?
Traditional web applications used server-side sessions for authentication. After login, the server stored session data in memory or a database, gave the browser a session ID cookie, and looked up the session on every request.
This worked fine for simple applications. But as web architecture evolved — microservices, mobile apps, APIs, distributed systems — session-based authentication created problems:
- Scalability — Session data stored on one server means all requests must go to that server, or session data must be shared across servers
- Mobile apps — Cookies work in browsers but are awkward in mobile apps and APIs
- Microservices — Multiple independent services cannot easily share a central session store
- Cross-domain — Sessions do not work cleanly when the frontend and backend are on different domains
JWT was created to solve these problems with a stateless, portable, self-contained token that works everywhere.
9 Powerful Concepts of JWT
Concept 1: The Three Parts of a JWT 🏗️
The most fundamental thing to understand about what is JWT is its structure. Every JWT consists of exactly three parts, separated by dots:
Let us decode that example JWT from earlier:
Part 1 — Header (Algorithm and Token Type)
json
{
"alg": "HS256",
"typ": "JWT"
}
The header tells the recipient how the JWT is signed — what algorithm was used. HS256 means HMAC-SHA256.
Part 2 — Payload (The Claims / Data)
json
{
"userId": 123,
"name": "Rahul",
"role": "admin",
"iat": 1716239022,
"exp": 1716242622
}
This is the actual data inside the token — called claims. Here we can see the user’s ID, name, role, when the token was issued (iat = issued at), and when it expires (exp).
Part 3 — Signature (Tamper Protection)
HMACSHA256(
base64UrlEncode(header) + "." + base64UrlEncode(payload),
your-256-bit-secret
)
The signature is created by running the encoded header and payload through a hashing algorithm along with a secret key. It is what makes JWT trustworthy — if anyone modifies the payload, the signature will no longer match and the token is rejected.
Important note: What is JWT’s payload security? The payload is Base64-encoded — not encrypted. Anyone can decode it and read the data inside. Never put passwords, credit card numbers, or other sensitive data in a JWT payload. Use HTTPS to protect the token in transit.
Concept 2: JWT Claims — What Lives Inside the Token 📋
Claims are the pieces of information stored in the JWT payload. Understanding claims is central to understanding what is JWT used for in practice.
There are three types of claims:
Registered Claims (Standardized) These are predefined claim names with specific meanings:
| Claim |
Full Name |
Meaning |
iss |
Issuer |
Who created the token (e.g., “myapp.com”) |
sub |
Subject |
Who the token is about (e.g., user ID) |
aud |
Audience |
Who the token is intended for |
exp |
Expiration Time |
When the token expires (Unix timestamp) |
nbf |
Not Before |
Token not valid before this time |
iat |
Issued At |
When the token was created |
jti |
JWT ID |
Unique identifier for the token |
Public Claims Custom claims registered in the IANA JSON Web Token Claims registry to avoid conflicts.
Private Claims Custom claims agreed upon between parties — not registered anywhere. Most application-specific data lives here.
json
{
"sub": "user_123",
"iss": "https://auth.myapp.com",
"exp": 1716242622,
"iat": 1716239022,
"name": "Rahul Sharma",
"email": "rahul@email.com",
"role": "admin",
"plan": "premium"
}
The last four fields — name, email, role, plan — are private claims specific to this application.
Concept 3: How JWT Authentication Works — Step by Step 🔄
Understanding what is JWT in practice means knowing the complete authentication flow.
Step 1 — User Logs In User sends username and password to the authentication endpoint.
POST /api/auth/login
{ "email": "rahul@email.com", "password": "secret123" }
Step 2 — Server Verifies Credentials Server checks the credentials against the database. If valid, it creates a JWT containing the user’s data, signs it with a secret key, and sends it back.
json
{
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"expiresIn": 3600
}
Step 3 — Client Stores the Token The client stores the JWT — typically in memory (safest for SPAs) or localStorage (convenient but XSS-vulnerable).
Step 4 — Client Sends Token with Requests For every subsequent API request, the client includes the JWT in the Authorization header:
GET /api/user/profile
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
Step 5 — Server Verifies the Token The server receives the request, extracts the JWT from the header, verifies the signature using its secret key, checks the expiration time, and processes the request.
Incoming JWT
↓
Decode Header + Payload
↓
Recalculate Signature using Secret Key
↓
Signatures Match? → ✅ Trust the token, process request
Signatures Don't Match? → ❌ Reject the request (tampered token)
Step 6 — Server Responds If the token is valid, the server processes the request and returns the response. No database lookup for authentication — everything the server needs is in the token itself.
Concept 4: JWT Signing Algorithms 🔐
What is JWT’s security based on? The signing algorithm. Choosing the right one matters.
HS256 — HMAC with SHA-256 (Symmetric) Uses a single secret key for both signing and verification. Fast and simple. The catch: both the issuer and verifier must share the same secret. Fine for single-service applications, but problematic when multiple services need to verify tokens independently.
Sign: JWT = encode(header + payload) + HMAC(header + payload, secret)
Verify: Recalculate HMAC and compare
RS256 — RSA with SHA-256 (Asymmetric) Uses a private key for signing and a public key for verification. The private key never leaves the authentication server. Any service can verify tokens using the public key without being able to create them. Best for microservices and distributed systems.
Sign: JWT = encode(header + payload) + RSA_sign(header + payload, privateKey)
Verify: RSA_verify(signature, publicKey)
ES256 — ECDSA with SHA-256 (Asymmetric) Similar to RS256 but using Elliptic Curve cryptography. Produces shorter signatures than RSA with equivalent security. Increasingly preferred in 2026 for its performance advantages.
Algorithm recommendations in 2026:
- Single-server app or simple API: HS256 is fine
- Microservices or multiple consumers: RS256 or ES256
- Never use: none (no signature — allows anyone to forge tokens)
Concept 5: JWT vs Session-Based Authentication 🆚
This is one of the most discussed comparisons in the what is JWT conversation. Both approaches have real trade-offs.
Session-Based Authentication:
1. User logs in
2. Server creates session, stores it in database
3. Server gives browser a session ID cookie
4. Every request: server looks up session ID in database
5. Database returns session data → request processed
JWT Authentication:
1. User logs in
2. Server creates JWT with user data, signs it
3. Server gives client the JWT
4. Every request: server verifies JWT signature (no DB lookup)
5. Data in JWT → request processed
Full comparison:
| Feature |
Session |
JWT |
| State |
Stateful (server stores sessions) |
Stateless (server stores nothing) |
| Storage |
Server database |
Client side |
| Scalability |
Harder (shared session store needed) |
Easier (no shared state) |
| Revocation |
Easy (delete session from DB) |
Hard (token valid until expiry) |
| Performance |
DB lookup every request |
Cryptographic verify (fast) |
| Mobile/API |
Awkward (cookies) |
Natural (Bearer header) |
| Cross-domain |
Difficult |
Simple |
| Token size |
Small session ID |
Larger JWT |
| Best for |
Traditional web apps |
APIs, SPAs, microservices |
The biggest JWT limitation is revocation. With sessions, logging out is simple — delete the session from the database. With JWT, the token remains valid until it expires. This is why short expiry times and refresh token rotation are critical.
Concept 6: Access Tokens and Refresh Tokens with JWT 🔄
What is JWT’s solution to the short-expiry problem? A two-token system.
Access Token A short-lived JWT used for API requests. Typically expires in 15 minutes to 1 hour. Short expiry limits damage if stolen.
Refresh Token A long-lived token (not necessarily a JWT) stored securely server-side. Used only to get a new access token when the current one expires. Can be revoked.
The flow:
Login → Access Token (15 min) + Refresh Token (7 days)
↓
Access Token expires
↓
Client sends Refresh Token to /auth/refresh
↓
Server validates Refresh Token (checks database)
↓
Issues new Access Token (15 min) + rotates Refresh Token
Refresh Token Rotation is critical in 2026. Every time a refresh token is used, it gets replaced with a new one. If an old refresh token is used again, it signals a potential theft — the server immediately revokes all refresh tokens for that user.
Concept 7: JWT Security Best Practices 🛡️
What is JWT security like when done correctly? Very strong. When done poorly? Dangerous. Here are the non-negotiable best practices.
Always verify the signature Never trust a JWT without verifying the signature. Some early JWT libraries had a vulnerability where setting the algorithm to “none” bypassed signature verification entirely. Always explicitly specify which algorithms are acceptable.
Keep expiry times short Access tokens should expire in 15–60 minutes. The longer a token lives, the more damage it can do if stolen.
Never put sensitive data in the payload JWT payloads are Base64-encoded — not encrypted. Anyone who gets the token can read the payload. Never store passwords, financial data, or other secrets in a JWT.
Use HTTPS everywhere A JWT intercepted in transit is just as dangerous as a stolen password. All endpoints accepting JWTs must use HTTPS.
Store tokens securely on the client
- SPAs: Store in memory (lost on page refresh, but safe from XSS)
- If localStorage: Accept XSS risk and mitigate with Content Security Policy
- Cookies: Use HttpOnly and Secure flags to prevent JavaScript access
- Mobile: Use platform secure storage (Keychain/Keystore)
Implement token revocation Use a token blacklist or short-lived tokens with refresh token rotation to handle logout and compromised token scenarios.
Validate all claims Always check exp (not expired), iss (expected issuer), aud (intended for this service), and nbf (not used before valid time).
Concept 8: JWT Encoding vs Encryption — A Common Confusion 🔍
One of the most common misconceptions about what is JWT is that it is encrypted. It is not — unless you use JWE.
Standard JWT (JWS — JSON Web Signature): The payload is Base64Url encoded — reversible by anyone. The signature proves it has not been tampered with, but the data is readable.
Anyone can decode the payload:
eyJ1c2VySWQiOjEyM30 → {"userId": 123}
JWE (JSON Web Encryption): The payload is actually encrypted — only the recipient with the private key can read it. JWE is less common but used when payload confidentiality is required.
What is JWT protection model?
- Integrity — The signature guarantees nobody modified the token
- Confidentiality — NOT provided by standard JWT (use JWE or HTTPS for this)
This distinction matters when deciding what data to put in a JWT. User ID and role — fine. Medical history or financial data — use JWE or keep it out of the token entirely.
Concept 9: When NOT to Use JWT ⚠️
Understanding what is JWT also means knowing its limits. JWT is powerful but not always the right tool.
Do not use JWT when you need instant revocation Because JWT is stateless, a token issued to a user remains valid until it expires — even if you “log them out.” This matters for high-security applications where immediate session termination is required (banking, healthcare).
Do not use JWT for long-lived sessions without a refresh token system A JWT with a 30-day expiry is dangerous. If stolen, the attacker has 30 days of access. Always combine short-lived JWTs with a proper refresh token rotation system.
Do not store large amounts of data in JWT Every JWT is sent with every API request. A JWT with 50 claims adds kilobytes of overhead to every request. Keep JWTs lean — store only what is genuinely needed.
Do not use JWT as a database replacement Some developers put so much data in JWTs that they never need to query the database. This is an anti-pattern. JWTs should contain the minimum data needed for authorization decisions, not an entire user profile.
Consider sessions instead when:
- You are building a traditional server-rendered web app
- You need reliable, instant session revocation
- Your users access the app only through a browser
- You have a single-server architecture with no scaling concerns