Authorization & Role-Based Access
Authorization answers "What are you allowed to do?" It runs after authentication and determines whether an authenticated user has permission to access a specific resource or perform an action.
1 RBAC — Role-Based Access Control
JavaScript — Role Middleware (Express)
// Define roles and their permissions
const ROLES = {
user: ["read:own"],
editor: ["read:any", "write:own"],
admin: ["read:any", "write:any", "delete:any"]
};
// Middleware factory — authorize by role
function authorize(...allowedRoles) {
return (req, res, next) => {
if (!req.user) return res.status(401).json({ error: "Not authenticated" });
if (!allowedRoles.includes(req.user.role)) {
return res.status(403).json({
error: "Forbidden",
message: "You don't have permission to perform this action"
});
}
next();
};
}
// Usage on routes
router.get("/users", authenticate, authorize("admin"), getAllUsers);
router.delete("/users/:id", authenticate, authorize("admin"), deleteUser);
router.patch("/posts/:id", authenticate, authorize("admin", "editor"), updatePost);
router.get("/profile", authenticate, getProfile); // any authenticated
2 Resource Ownership Check
JavaScript — Ownership Guard
// Only the owner (or admin) can edit their resource
async function canEditPost(req, res, next) {
const post = await Post.findById(req.params.id);
if (!post) return res.status(404).json({ error: "Post not found" });
const isOwner = post.authorId.toString() === req.user.userId;
const isAdmin = req.user.role === "admin";
if (!isOwner && !isAdmin) {
return res.status(403).json({ error: "You can only edit your own posts" });
}
req.post = post; // attach for the next handler
next();
}
router.put("/posts/:id", authenticate, canEditPost, updatePost);
3 Code Challenge
Challenge: Implement a permission system where
admin can CRUD all users, editor can read all and update their own profile, and user can only read and update their own profile. Write the middleware for each scenario.