What is JWT Authentication in Node.js?
Learn how JWT authentication works in Node.js and Express, its token structure, security best practices, and refresh token patterns with code.
Expected Interview Answer
JWT (JSON Web Token) authentication is a stateless auth scheme where the server issues a signed token containing user claims after login, and the client sends that token on every subsequent request instead of the server maintaining a session store.
A JWT has three base64url-encoded parts separated by dots: header (algorithm/type), payload (claims like userId, role, expiry), and signature (HMAC or RSA signature over header+payload using a secret/private key). The server verifies the signature on each incoming request to trust the payload without a database lookup, which scales well across multiple servers since no shared session store is required. In Node/Express, libraries like jsonwebtoken sign and verify tokens, and middleware extracts the token from the Authorization header, verifies it, and attaches the decoded user to req.user. JWTs should be short-lived and paired with refresh tokens, stored in httpOnly cookies (not localStorage) to reduce XSS risk, and never contain sensitive secrets since the payload is only encoded, not encrypted.
- Stateless — no server-side session store needed
- Scales easily across multiple server instances
- Self-contained claims reduce database lookups
- Works well for APIs and mobile/SPA clients
- Standardized format supported across languages
AI Mentor Explanation
JWT auth is like a tamper-proof accreditation badge issued at the stadium gate, stamped with your seat section and access level, so security at every checkpoint can verify it instantly without radioing back to the ticket office. If anyone tries to forge or alter the stamp, the hologram breaks and security rejects it on the spot.
JWT authentication flow
Login request
- Client sends credentials
- Server validates and signs JWT
JWT token
- Header + Payload + Signature
- Sent via Authorization: Bearer header
Protected route
- Middleware verifies signature
- Attaches req.user from payload
Step-by-Step Explanation
Step 1
User logs in
Client sends credentials; server validates them against the database.
Step 2
Server signs a JWT
Using jsonwebtoken.sign(payload, secret, { expiresIn }), embedding user claims.
Step 3
Client stores and sends the token
Ideally in an httpOnly cookie, sent automatically or via Authorization: Bearer header.
Step 4
Middleware verifies on each request
jwt.verify() checks the signature and expiry before allowing access.
Step 5
Attach decoded user to request
req.user = decoded lets downstream route handlers access identity/claims.
Step 6
Use short-lived tokens with refresh
Issue a short-lived access token plus a longer-lived refresh token to balance security and UX.
What Interviewer Expects
- Explains JWT structure: header, payload, signature
- Knows JWT auth is stateless, unlike session-cookie auth
- Understands signature verification, not encryption, protects the payload
- Mentions storing tokens securely (httpOnly cookies vs localStorage)
- Can discuss short-lived access tokens plus refresh token pattern
Common Mistakes
- Storing sensitive secrets directly in the JWT payload
- Assuming JWT payloads are encrypted rather than just encoded
- Storing tokens in localStorage, exposing them to XSS
- Using excessively long expiry times without refresh token rotation
- Not verifying signature/expiry before trusting decoded claims
Best Answer (HR Friendly)
“JWT authentication lets a server verify who a user is without storing their login session anywhere. After logging in, the user gets a secure signed token that proves their identity on every future request, making the system easier to scale across multiple servers.”
Code Example
const jwt = require('jsonwebtoken');
// After successful login
const token = jwt.sign({ userId: 42, role: 'admin' }, process.env.JWT_SECRET, { expiresIn: '15m' });
res.json({ token });
// Middleware to protect routes
function requireAuth(req, res, next) {
const token = req.headers.authorization?.split(' ')[1];
try {
req.user = jwt.verify(token, process.env.JWT_SECRET);
next();
} catch (err) {
res.status(401).json({ error: 'Invalid or expired token' });
}
}
// req.user -> { userId: 42, role: 'admin', iat: ..., exp: ... }Follow-up Questions
- What are the three parts of a JWT and what does each contain?
- Why is JWT authentication considered stateless?
- Where should you store a JWT on the client, and why?
- How do refresh tokens work alongside short-lived access tokens?
- How would you revoke a JWT before it expires?
MCQ Practice
1. What are the three parts of a JWT?
A JWT consists of a header, payload, and signature, each base64url-encoded and dot-separated.
2. Is the JWT payload encrypted?
The payload is encoded, not encrypted, so it should never contain sensitive secrets directly.
3. Why is JWT authentication considered stateless?
The server can verify a JWT's signature and claims without maintaining any server-side session store.
Flash Cards
What does JWT stand for? — JSON Web Token — a signed token format for stateless authentication.
Is a JWT payload encrypted? — No — it's base64url-encoded and signed, not encrypted, so avoid secrets in it.
Where should JWTs be stored client-side? — Preferably in httpOnly cookies, not localStorage, to reduce XSS risk.
What pairs with short-lived access tokens? — A longer-lived refresh token used to obtain new access tokens.