Implementing Role-Based Access Control (RBAC) in Node.js with Express.js is an essential step for securing your web application. RBAC allows you to define roles and permissions, ensuring users can only access resources they are authorized for. This article provides a step-by-step guide to integrating RBAC into your Express.js project.

Understanding RBAC in Node.js

Role-Based Access Control (RBAC) is a method of restricting system access to authorized users based on their assigned roles. In Node.js, especially with Express.js, implementing RBAC involves defining roles, permissions, and middleware to enforce access rules.

Setting Up Your Project

Start by creating a new Node.js project and installing necessary packages:

  • Initialize npm: npm init -y
  • Install Express: npm install express
  • Install JSON Web Token (JWT) for authentication: npm install jsonwebtoken
  • Install bcrypt for password hashing: npm install bcrypt

Defining Roles and Permissions

Create a roles and permissions structure. For example:

Roles: Admin, Editor, Viewer

Permissions: read, write, delete

Implement this as a JavaScript object:

{
  roles: {
    admin: ['read', 'write', 'delete'],
    editor: ['read', 'write'],
    viewer: ['read']
  }
}

Creating Middleware for Access Control

Develop middleware to check user roles and permissions before allowing access to routes:

function authorize(requiredPermissions) {
  return (req, res, next) => {
    const userRole = req.user.role;
    const permissions = roles[userRole] || [];
    const hasPermission = requiredPermissions.every(p => permissions.includes(p));
    if (hasPermission) {
      next();
    } else {
      res.status(403).json({ message: 'Forbidden' });
    }
  };
}

Implementing Authentication

Use JWT for authenticating users. Create login routes that generate tokens:

app.post('/login', (req, res) => {
  const { username, password } = req.body;
  // Validate user credentials from database
  const user = getUserFromDB(username);
  if (user && bcrypt.compareSync(password, user.password)) {
    const token = jwt.sign({ id: user.id, role: user.role }, 'secretKey', { expiresIn: '1h' });
    res.json({ token });
  } else {
    res.status(401).json({ message: 'Invalid credentials' });
  }
});

Protecting Routes with RBAC

Apply the middleware to secure endpoints based on roles and permissions:

app.get('/admin', authenticateToken, authorize(['read', 'write', 'delete']), (req, res) => {
  res.send('Welcome to admin panel.');
});

Conclusion

Implementing RBAC in Node.js with Express.js enhances your application's security by ensuring users access only what they are authorized for. Combining role definitions, middleware, and JWT authentication provides a robust access control system.