Role Based Access Control in Express: Simple Implementation Guide
To implement role based access in
Express, create middleware that checks the user's role from the request and allows or denies access accordingly. Use this middleware on routes to restrict access based on roles like admin or user.Syntax
The core syntax involves creating a middleware function that takes allowed roles as input and returns a function checking the user's role from req.user. If the role matches, it calls next() to continue; otherwise, it sends a 403 Forbidden response.
Use it in routes like app.get('/admin', roleMiddleware(['admin']), handler).
javascript
function roleMiddleware(allowedRoles) { return (req, res, next) => { const userRole = req.user?.role; if (allowedRoles.includes(userRole)) { next(); } else { res.status(403).send('Access denied'); } }; }
Example
This example shows a simple Express app with a mock user and role-based middleware protecting an admin route.
javascript
import express from 'express'; const app = express(); // Mock user middleware to simulate logged-in user app.use((req, res, next) => { req.user = { id: 1, role: 'admin' }; // Change role to 'user' to test access denial next(); }); // Role based access middleware function roleMiddleware(allowedRoles) { return (req, res, next) => { const userRole = req.user?.role; if (allowedRoles.includes(userRole)) { next(); } else { res.status(403).send('Access denied'); } }; } // Protected admin route app.get('/admin', roleMiddleware(['admin']), (req, res) => { res.send('Welcome Admin!'); }); // Open route app.get('/', (req, res) => { res.send('Public content'); }); app.listen(3000, () => console.log('Server running on http://localhost:3000'));
Output
Server running on http://localhost:3000
GET /admin returns 'Welcome Admin!' if user role is 'admin'
GET /admin returns 'Access denied' with 403 if user role is not 'admin'
GET / returns 'Public content'
Common Pitfalls
- Not setting
req.userbefore the role check middleware causes errors or wrong access decisions. - Forgetting to handle the case when
req.userorreq.user.roleis undefined. - Hardcoding roles in multiple places instead of centralizing role definitions.
- Not sending proper HTTP status codes like 403 for forbidden access.
javascript
/* Wrong way: No user set, no role check */ app.get('/admin', (req, res) => { if (req.user?.role === 'admin') { res.send('Welcome Admin!'); } else { res.status(403).send('Access denied'); } }); /* Right way: Use middleware and check safely */ function roleMiddleware(allowedRoles) { return (req, res, next) => { const userRole = req.user?.role; if (allowedRoles.includes(userRole)) { next(); } else { res.status(403).send('Access denied'); } }; }
Quick Reference
Use this quick reference to implement role based access control in Express:
| Step | Description |
|---|---|
| 1 | Create middleware that accepts allowed roles. |
| 2 | Check req.user.role inside middleware. |
| 3 | Call next() if role allowed, else send 403. |
| 4 | Apply middleware to routes needing protection. |
| 5 | Ensure req.user is set before middleware runs. |
Key Takeaways
Create middleware that checks user roles from req.user to control access.
Always send HTTP 403 status when access is denied for clarity.
Ensure user info is set on req before role checks to avoid errors.
Apply role middleware on routes to restrict access based on roles.
Centralize role definitions to avoid duplication and mistakes.