Implementing Role-Based Access Control (RBAC) in a Node.js application involves defining roles, associating those roles with permissions, and then enforcing access control based on the roles assigned to users. Here's a step-by-step guide on how you can implement RBAC in a Node.js application:
Install packages that will help you manage roles and permissions. Two popular packages are jsonwebtoken
for handling JSON Web Tokens (JWT) and express
for building web applications.
bashnpm install express jsonwebtoken
Define roles and associated permissions in your application. You can do this by creating a module that exports an object with roles as keys and arrays of permissions as values.
javascript// roles.js
module.exports = {
admin: ['read', 'write', 'delete'],
user: ['read'],
guest: []
};
Create a middleware function that checks whether the user has the required role to access a particular route.
javascript// authMiddleware.js
const roles = require('./roles');
function authorize(role) {
return (req, res, next) => {
const userRole = req.user.role; // Assuming you store user role in req.user
if (roles[userRole].includes(role)) {
return next();
} else {
return res.status(403).json({ message: 'Permission denied' });
}
};
}
module.exports = authorize;
Implement JWT for user authentication. Create a middleware that verifies the JWT and sets the user information in the request object.
javascript// authMiddleware.js
const jwt = require('jsonwebtoken');
function authenticate(req, res, next) {
const token = req.header('Authorization');
if (!token) {
return res.status(401).json({ message: 'Unauthorized' });
}
try {
const decoded = jwt.verify(token, 'your-secret-key');
req.user = decoded.user;
next();
} catch (error) {
res.status(401).json({ message: 'Invalid token' });
}
}
module.exports = authenticate;
Use the created middleware to protect routes based on roles.
javascript// routes.js
const express = require('express');
const authenticate = require('./authMiddleware');
const authorize = require('./authorizeMiddleware');
const roles = require('./roles');
const app = express();
// Example of a protected route for admins
app.get('/admin', authenticate, authorize('admin'), (req, res) => {
res.json({ message: 'Admin route accessed' });
});
// Example of a protected route for users
app.get('/user', authenticate, authorize('user'), (req, res) => {
res.json({ message: 'User route accessed' });
});
// Public route
app.get('/public', (req, res) => {
res.json({ message: 'Public route accessed' });
});
app.listen(3000, () => {
console.log('Server is running on port 3000');
});
Test your RBAC implementation by making requests to the protected routes with different roles. Make sure that users with the correct roles can access the routes, while others receive a permission denied message.
This is a basic example, and you can extend it based on your application's requirements. Additionally, you might want to consider using a more robust solution, such as the casbin
library, for a more comprehensive RBAC implementation.