Role-Based Access ControlLesson 5.2
implementing permission middleware in Express
permission check middleware, hasPermission helper, role-permission mapping, middleware factory pattern, combining auth and authz middleware, error response consistency
Permission Middleware in Express
Build permission checks as composable middleware that reads from a role-permission map.
const ROLE_PERMISSIONS = {
viewer: new Set(['post:read']),
editor: new Set(['post:read', 'post:create', 'post:update:own']),
admin: new Set(['post:read', 'post:create', 'post:update:any', 'post:delete:any', 'user:ban'])
};
function hasPermission(role, permission) {
return ROLE_PERMISSIONS[role]?.has(permission) ?? false;
}
// Middleware factory
function requirePermission(permission) {
return (req, res, next) => {
if (!req.user) {
return res.status(401).json({ error: 'Authentication required' });
}
if (!hasPermission(req.user.role, permission)) {
return res.status(403).json({ error: 'Insufficient permissions' });
}
next();
};
}
// Usage
app.delete('/posts/:id',
requireAuth,
requirePermission('post:delete:any'),
deletePostHandler
);
Centralize your permission map. Never scatter role checks inline through route handlers — a change to roles requires hunting through the codebase. One source of truth means one place to update.
Use Set for permission collections — O(1) lookup vs O(n) for arrays, which matters when checking permissions on every request.
