0
0
ExpressHow-ToBeginner · 3 min read

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.user before the role check middleware causes errors or wrong access decisions.
  • Forgetting to handle the case when req.user or req.user.role is 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:

StepDescription
1Create middleware that accepts allowed roles.
2Check req.user.role inside middleware.
3Call next() if role allowed, else send 403.
4Apply middleware to routes needing protection.
5Ensure 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.