How to Test Authentication in Express: Simple Guide
To test authentication in
Express, use a testing library like supertest to simulate HTTP requests and check responses. Write tests that send login credentials and verify protected routes respond correctly with or without valid tokens or sessions.Syntax
Testing authentication in Express involves sending HTTP requests to your app's endpoints and checking the responses. Use supertest to create requests and Jest or another test runner to assert results.
Key parts:
request(app).post('/login'): sends a POST request to login route..send({ username, password }): sends login data..expect(statusCode): checks HTTP response code.set('Authorization', 'Bearer token'): adds auth header for protected routes.
javascript
import request from 'supertest'; import app from './app'; // your Express app describe('Authentication Tests', () => { it('logs in user', async () => { const response = await request(app) .post('/login') .send({ username: 'user', password: 'pass' }) .expect(200); expect(response.body.token).toBeDefined(); }); it('accesses protected route with token', async () => { const login = await request(app) .post('/login') .send({ username: 'user', password: 'pass' }); const token = login.body.token; await request(app) .get('/protected') .set('Authorization', `Bearer ${token}`) .expect(200); }); });
Example
This example shows a simple Express app with a login route that returns a token and a protected route that requires the token. The test logs in, gets the token, then accesses the protected route.
javascript
import express from 'express'; import request from 'supertest'; import jwt from 'jsonwebtoken'; const app = express(); app.use(express.json()); const SECRET = 'secretkey'; // Dummy user data const user = { id: 1, username: 'user', password: 'pass' }; app.post('/login', (req, res) => { const { username, password } = req.body; if (username === user.username && password === user.password) { const token = jwt.sign({ id: user.id }, SECRET); return res.json({ token }); } res.status(401).json({ message: 'Invalid credentials' }); }); app.get('/protected', (req, res) => { const authHeader = req.headers['authorization']; if (!authHeader) return res.status(401).json({ message: 'No token' }); const token = authHeader.split(' ')[1]; try { jwt.verify(token, SECRET); res.json({ message: 'Protected data' }); } catch { res.status(403).json({ message: 'Invalid token' }); } }); // Tests describe('Auth Test Suite', () => { it('should login and get token', async () => { const res = await request(app) .post('/login') .send({ username: 'user', password: 'pass' }) .expect(200); expect(res.body.token).toBeDefined(); }); it('should deny access without token', async () => { await request(app) .get('/protected') .expect(401); }); it('should access protected route with valid token', async () => { const loginRes = await request(app) .post('/login') .send({ username: 'user', password: 'pass' }); const token = loginRes.body.token; const protectedRes = await request(app) .get('/protected') .set('Authorization', `Bearer ${token}`) .expect(200); expect(protectedRes.body.message).toBe('Protected data'); }); });
Output
PASS ./auth.test.js
Auth Test Suite
✓ should login and get token (XX ms)
✓ should deny access without token (XX ms)
✓ should access protected route with valid token (XX ms)
Common Pitfalls
- Not sending the token in the
Authorizationheader causes 401 errors. - Using expired or invalid tokens leads to 403 errors.
- Forgetting to parse JSON body with
express.json()breaks login data reading. - Testing without awaiting async calls can cause false positives or errors.
Always check your test waits for responses and sets headers correctly.
javascript
/* Wrong: Missing token header */ await request(app) .get('/protected') .expect(401); /* Right: Set Authorization header */ await request(app) .get('/protected') .set('Authorization', `Bearer ${token}`) .expect(200);
Quick Reference
Tips for testing Express authentication:
- Use
supertestto simulate HTTP requests. - Send login data with
.send()and check for tokens. - Include tokens in
Authorizationheaders for protected routes. - Check status codes:
200for success,401for missing token,403for invalid token. - Use async/await to handle asynchronous tests properly.
Key Takeaways
Use supertest to send HTTP requests and check authentication responses in Express.
Always include the token in the Authorization header to access protected routes.
Check for correct status codes: 200 for success, 401 for missing token, 403 for invalid token.
Parse JSON bodies with express.json() middleware to read login data.
Write async tests with await to ensure proper test execution.