How to Use JWT for REST API Authentication
Use
JWT by generating a token after user login, then send this token in the Authorization header for each REST API request. The server verifies the token to authenticate the user without storing session data.Syntax
The basic flow for JWT authentication in REST APIs involves these steps:
- Token generation: Create a JWT with user info and a secret key after login.
- Token sending: Client sends the JWT in the
Authorizationheader asBearer <token>with each request. - Token verification: Server checks the token's signature and expiry to authenticate the user.
http
POST /login
Request body: {"username": "user", "password": "pass"}
Response: {"token": "<JWT_TOKEN>"}
GET /protected-resource
Headers: Authorization: Bearer <JWT_TOKEN>Example
This example shows a simple Node.js REST API using jsonwebtoken to create and verify JWTs for authentication.
javascript
import express from 'express'; import jwt from 'jsonwebtoken'; const app = express(); app.use(express.json()); const SECRET_KEY = 'your-secret-key'; // Login route to generate token app.post('/login', (req, res) => { const { username, password } = req.body; // Simple user check (replace with real validation) if (username === 'user' && password === 'pass') { const token = jwt.sign({ username }, SECRET_KEY, { expiresIn: '1h' }); return res.json({ token }); } res.status(401).json({ message: 'Invalid credentials' }); }); // Middleware to verify token function authenticateToken(req, res, next) { const authHeader = req.headers['authorization']; const token = authHeader && authHeader.split(' ')[1]; if (!token) return res.status(401).json({ message: 'Token missing' }); jwt.verify(token, SECRET_KEY, (err, user) => { if (err) return res.status(403).json({ message: 'Token invalid' }); req.user = user; next(); }); } // Protected route app.get('/protected', authenticateToken, (req, res) => { res.json({ message: `Hello, ${req.user.username}! This is protected.` }); }); app.listen(3000, () => console.log('Server running on http://localhost:3000'));
Output
POST /login with {"username":"user","password":"pass"} returns {"token":"<JWT_TOKEN>"}
GET /protected with header Authorization: Bearer <JWT_TOKEN> returns {"message":"Hello, user! This is protected."}
Common Pitfalls
- Not verifying the token: Always verify the token signature and expiry on the server to avoid unauthorized access.
- Sending token insecurely: Use HTTPS to protect tokens in transit.
- Storing tokens insecurely: Store tokens safely on the client side, e.g., in memory or secure storage, not in localStorage if XSS is a risk.
- Ignoring token expiration: Handle expired tokens by prompting users to log in again.
javascript
/* Wrong: Not verifying token */ app.get('/protected', (req, res) => { // No token check here res.json({ message: 'Access granted without verification' }); }); /* Right: Verify token with middleware */ function authenticateToken(req, res, next) { const authHeader = req.headers['authorization']; const token = authHeader && authHeader.split(' ')[1]; if (!token) return res.status(401).json({ message: 'Token missing' }); jwt.verify(token, SECRET_KEY, (err, user) => { if (err) return res.status(403).json({ message: 'Token invalid' }); req.user = user; next(); }); }
Quick Reference
- Generate token: Use
jwt.sign(payload, secret, options). - Send token: Include in
Authorization: Bearer <token>header. - Verify token: Use
jwt.verify(token, secret)on server. - Protect routes: Use middleware to check token before access.
Key Takeaways
Generate JWT after user login and send it in the Authorization header for API requests.
Always verify JWT signature and expiration on the server to authenticate users securely.
Use HTTPS to protect tokens during transmission and store tokens securely on the client.
Handle token expiration by prompting users to re-authenticate.
Use middleware to protect API routes by checking JWT before granting access.