JWT Authentication
JSON Web Tokens let a client prove its identity without server-side sessions.
Syntax
jwt.sign(payload, secret)A JWT (JSON Web Token) is a signed token the server issues at login. The client sends it back on each request, usually in the Authorization: Bearer header. The server verifies the signature instead of looking up a session.
JWTs are popular for APIs because they are stateless. Use the jsonwebtoken package to sign and verify them.
Example
const jwt = require('jsonwebtoken');
app.post('/login', (req, res) => {
const token = jwt.sign({ userId: 42 }, process.env.JWT_SECRET, {
expiresIn: '1h',
});
res.json({ token });
});
function auth(req, res, next) {
const token = req.headers.authorization?.split(' ')[1];
try {
req.user = jwt.verify(token, process.env.JWT_SECRET);
next();
} catch {
res.status(401).json({ error: 'Invalid token' });
}
}When to use it
- A mobile API issues a signed JWT on login so the client can include it in the Authorization header for every subsequent API call.
- A microservices architecture passes a JWT between services to propagate the authenticated user's identity without shared session storage.
- A developer sets a short JWT expiry (15 minutes) and issues a longer-lived refresh token to limit the window of exposure from a stolen token.
More examples
Issue a JWT on login
Signs a JWT payload containing the username and role, returning it to the client for use in future requests.
const jwt = require('jsonwebtoken');
app.post('/login', (req, res) => {
const { username } = req.body;
// In reality, verify credentials against DB first
const token = jwt.sign(
{ sub: username, role: 'user' },
process.env.JWT_SECRET,
{ expiresIn: '1h' }
);
res.json({ token });
});Verify JWT middleware
Extracts the Bearer token, verifies its signature and expiry, and attaches the decoded payload to req.user.
const jwt = require('jsonwebtoken');
function requireJwt(req, res, next) {
const auth = req.headers.authorization || '';
const token = auth.replace('Bearer ', '');
try {
req.user = jwt.verify(token, process.env.JWT_SECRET);
next();
} catch {
res.status(401).json({ error: 'Invalid or expired token' });
}
}
app.get('/profile', requireJwt, (req, res) => res.json(req.user));Refresh token endpoint
Accepts a refresh token, verifies it with a separate secret, and issues a new short-lived access token.
app.post('/refresh', (req, res) => {
const { refreshToken } = req.body;
try {
const payload = jwt.verify(refreshToken, process.env.REFRESH_SECRET);
const newAccess = jwt.sign(
{ sub: payload.sub, role: payload.role },
process.env.JWT_SECRET,
{ expiresIn: '15m' }
);
res.json({ accessToken: newAccess });
} catch {
res.status(401).json({ error: 'Invalid refresh token' });
}
});
Discussion