How does token-based authentication with JWT work in a REST API?
Understand how JWT authentication works in REST APIs: the header, payload, signature, stateless verification, expiry, and refresh token best practices.
Expected Interview Answer
With JWT-based authentication, a client logs in once, the server returns a signed JSON Web Token, and the client sends that token in the Authorization header on every subsequent request. The server verifies the signature to trust the request without storing session state.
A JWT has three base64url parts: a header (algorithm), a payload (claims like user id, roles, and expiry), and a signature created with a secret or private key. Because the signature covers the header and payload, any tampering is detectable, so the server can trust the claims after verifying it. This makes JWTs stateless and horizontally scalable, but tokens cannot be easily revoked before they expire, so short lifetimes plus refresh tokens are standard.
- Stateless: no server-side session store needed
- Scales cleanly across multiple API instances
- Self-contained claims reduce database lookups
- Works well across domains and mobile clients
- Tamper-evident via cryptographic signature
AI Mentor Explanation
A JWT is like a tamper-proof match-day wristband stamped by the ground authority. Once security bands you at entry, every steward inside can glance at the hologram and let you pass without phoning the box office again. Alter the band and the seal breaks, exposing the forgery instantly, just as editing a token invalidates its signature.
Step-by-Step Explanation
Step 1
Login
The client submits credentials to an auth endpoint; the server verifies them against its user store.
Step 2
Issue token
On success the server builds a JWT with claims (sub, roles, exp) and signs it with a secret or private key.
Step 3
Store client-side
The client keeps the token, typically in memory or an HttpOnly cookie, and discards the raw credentials.
Step 4
Send on each request
The client attaches the token as 'Authorization: Bearer <jwt>' on every protected API call.
Step 5
Verify
The server checks the signature and expiry, then reads the claims to authenticate and authorize without a session lookup.
Step 6
Refresh or expire
When the short-lived token expires, the client uses a refresh token to obtain a new one, or re-authenticates.
What Interviewer Expects
- The three parts of a JWT: header, payload, signature
- Understanding that the signature ensures integrity, not confidentiality
- Why JWTs are stateless and how that aids scaling
- The role of exp, short lifetimes, and refresh tokens
- Awareness of revocation limitations and secure storage
Common Mistakes
- Thinking the payload is encrypted (it is only base64-encoded)
- Storing sensitive secrets or passwords inside the token
- Using long-lived tokens with no expiry or refresh strategy
- Accepting the 'alg: none' token or not pinning the algorithm
- Storing tokens in localStorage, exposing them to XSS
Best Answer (HR Friendly)
“The user logs in once and gets a digitally signed pass called a JWT. They send that pass with every request, and the server checks its signature to trust them without keeping a login session. It's like a tamper-proof wristband that any staff member can verify instantly.”
Code Example
const jwt = require('jsonwebtoken')
const SECRET = process.env.JWT_SECRET
// On login: sign a short-lived token
function login(req, res) {
const user = authenticateUser(req.body) // validates credentials
if (!user) return res.status(401).json({ error: 'Invalid login' })
const token = jwt.sign(
{ sub: user.id, roles: user.roles },
SECRET,
{ expiresIn: '15m' }
)
res.json({ token })
}
// On protected routes: verify the token
function auth(req, res, next) {
const token = (req.headers.authorization || '').replace('Bearer ', '')
try {
req.user = jwt.verify(token, SECRET, { algorithms: ['HS256'] })
next()
} catch (err) {
res.status(401).json({ error: 'Invalid or expired token' })
}
}Follow-up Questions
- How do refresh tokens complement short-lived access tokens?
- How would you revoke a JWT before it expires?
- What is the difference between JWT and opaque session tokens?
- Why is the 'alg: none' attack dangerous and how do you prevent it?
- Where should a browser client store a JWT securely?
MCQ Practice
1. What are the three parts of a JWT, in order?
A JWT is header.payload.signature, each base64url-encoded and separated by dots.
2. The JWT payload is protected how by default?
A standard signed JWT is not encrypted; anyone can decode the payload, so never put secrets in it. The signature only guarantees integrity.
3. Which claim controls when a JWT stops being valid?
The 'exp' claim holds the expiration timestamp; verifiers reject tokens past it.
Flash Cards
Three parts of a JWT — Header (algorithm), payload (claims), and signature, dot-separated and base64url-encoded.
Is a JWT payload encrypted? — No. It is only base64-encoded and readable; the signature only guarantees it wasn't altered.
Why are JWTs stateless? — Claims are self-contained and signature-verified, so no server-side session store is needed.
How are JWTs revoked? — Not easily before expiry, so use short lifetimes plus refresh tokens or a denylist.