التحكم في الوصول القائم على الأدوار
طوّروا برمجيات وسيطة للتفويض، وقيّدوا الوصول إلى مسارات API استنادًا إلى أدوار المستخدمين وأذوناتهم.
التحكم في الوصول القائم على الأدوار درس مجاني في Node.js Backend Development Bootcamp على CoddyKit. هذا هو الدرس 5 من أصل 6. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في Node.js Backend Development Bootcamp، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة Node.js Backend Development Bootcamp 6 دروس في المجموع.
بعض أجزاء هذا الدرس لم تُترجم بعد وتظهر باللغة الإنجليزية.
Intro to Role-Based Access Control
Welcome! In this lesson, we'll dive into Role-Based Access Control (RBAC). RBAC is a method of restricting system access based on the roles individual users have within an organization.
Think of it like a set of keys: each key (role) grants access to specific doors (resources or actions). Instead of giving each person a key to every door, you give them a keyring based on their job.
Importance of RBAC
RBAC is crucial for building secure and scalable applications. It offers several benefits:
- Improved Security: Users only access what they need.
- Simplified Management: Easier to manage permissions for groups rather than individuals.
- Reduced Errors: Less chance of granting incorrect access.
- Enhanced Compliance: Helps meet regulatory requirements for data access.
Without RBAC, managing permissions in a growing application becomes a nightmare!
Roles & Permissions Defined
It's important to understand the difference between roles and permissions:
- Role: A collection of permissions. Examples:
Admin,Editor,Viewer,Guest. - Permission: A specific action a user can perform. Examples:
read:post,write:post,delete:user.
A user is assigned one or more roles, and each role has a set of defined permissions. This structure makes access control flexible.
How to Store User Roles
When a user registers or logs in, their assigned roles need to be stored. Common ways to do this include:
- Database Field: A string (e.g.,
"admin","user") or an array of strings (e.g.,["admin", "editor"]) in the user's document/record. - JWT Payload: Include the roles directly in the JSON Web Token (JWT) during login. This makes them easily accessible on each request.
For our examples, we'll assume roles are available on the req.user object, which would be populated by a preceding authentication middleware (like one from a previous lesson).
Authorization Middleware Flow
In Express.js, middleware functions are perfect for authorization. An authorization middleware sits between the request and the route handler.
Here's how it works:
- A request comes in for a protected route.
- Our authorization middleware runs.
- It checks if the authenticated user has the necessary role(s).
- If yes, it calls
next()to pass control to the route handler. - If no, it sends an error response (e.g.,
403 Forbidden).
Define Role Check Middleware
We'll create a reusable middleware function that checks if an authenticated user has a specific role. This function accepts the requiredRole as an argument and returns another middleware function.
A real application would first have an authentication middleware populating req.user.
function authorizeRoles(requiredRole) {
return (req, res, next) => {
// Assume req.user is populated by auth middleware
// e.g., req.user = { id: 'abc', roles: ['user', 'editor'] }
if (!req.user || !req.user.roles || !req.user.roles.includes(requiredRole)) {
console.log(`Access Denied: Missing role '${requiredRole}'`);
return res.status(403).send('Forbidden: Insufficient role');
}
console.log(`Access Granted for role '${requiredRole}'`);
next(); // User has the required role, proceed
};
}
// To make it runnable for demonstration, let's wrap it in a mock Express-like setup
const mockReq = { user: { id: '123', roles: ['user', 'admin'] } };
const mockRes = {
status: function(code) { this.statusCode = code; return this; },
send: function(msg) { console.log(`Response Status: ${this.statusCode}, Message: ${msg}`); }
};
const mockNext = () => console.log('Next middleware/route handler called.');
console.log('--- Testing authorizeRoles("admin") ---');
const adminAuth = authorizeRoles('admin');
adminAuth(mockReq, mockRes, mockNext);
console.log('\n--- Testing authorizeRoles("guest") ---');
const guestAuth = authorizeRoles('guest');
guestAuth(mockReq, mockRes, mockNext);Protecting Routes with RBAC
Now, let's see how to apply our authorizeRoles middleware to protect specific routes in an Express.js application.
We can pass the middleware function directly to a route definition. Any request to that route will first pass through the authorization check.
const express = require('express');
const app = express();
// Mock authentication middleware (from previous lessons)
app.use((req, res, next) => {
// In a real app, this would verify a JWT and populate req.user
req.user = { id: 'user123', roles: ['user', 'viewer'] };
next();
});
// Our authorization middleware
function authorizeRoles(requiredRole) {
return (req, res, next) => {
if (!req.user || !req.user.roles.includes(requiredRole)) {
return res.status(403).send('Forbidden: Insufficient role');
}
next();
};
}
// Route accessible only by 'admin'
app.get('/admin-panel', authorizeRoles('admin'), (req, res) => {
res.send('Welcome to the Admin Panel!');
});
// Route accessible by 'user' or 'viewer' (since req.user has 'user', 'viewer')
app.get('/my-profile', authorizeRoles('user'), (req, res) => {
res.send(`Hello ${req.user.id}, this is your profile.`);
});
app.listen(3000, () => {
console.log('Server running on port 3000. Try accessing /admin-panel or /my-profile');
});Handling Multiple Required Roles
Sometimes a route might be accessible by more than one role (e.g., an Editor or an Admin). We can extend our middleware to accept multiple required roles.
The user just needs to have *at least one* of the specified roles to gain access.
const express = require('express');
const app = express();
// Mock authentication middleware
app.use((req, res, next) => {
req.user = { id: 'editor456', roles: ['user', 'editor'] };
next();
});
// Middleware to check for multiple roles
function authorizeAnyRole(requiredRoles) {
return (req, res, next) => {
if (!req.user || !req.user.roles) {
return res.status(403).send('Forbidden: User roles not found');
}
const hasRequiredRole = req.user.roles.some(role =>
requiredRoles.includes(role)
);
if (!hasRequiredRole) {
return res.status(403).send('Forbidden: Insufficient role(s)');
}
next();
};
}
// Route accessible by 'admin' OR 'editor'
app.get('/edit-content', authorizeAnyRole(['admin', 'editor']), (req, res) => {
res.send('You can edit content!');
});
// Route accessible by 'admin' only
app.get('/delete-all', authorizeAnyRole(['admin']), (req, res) => {
res.send('Danger Zone: All data deleted!');
});
app.listen(3000, () => {
console.log('Server running on port 3000. Try /edit-content or /delete-all');
});Beyond Roles: Granular Permissions
While roles are great for grouping permissions, sometimes you need more granular control. This is where explicit permissions come in.
- Instead of
authorizeRoles('admin'), you might haveauthorizePermission('delete:user'). - Your user object would then store an array of specific permissions (e.g.,
['read:post', 'update:post', 'delete:comment']).
This approach offers maximum flexibility but can increase complexity in managing permissions.
Check Your Understanding
Consider the following Express route setup:
// ... (assume authorizeRoles function is defined as in lesson)
app.use((req, res, next) => {
req.user = { id: 'testUser', roles: ['user', 'moderator'] };
next();
});
app.get('/moderate', authorizeRoles('moderator'), (req, res) => {
res.send('Moderator access granted.');
});
app.get('/admin-only', authorizeRoles('admin'), (req, res) => {
res.send('Admin access granted.');
});Recap & Next Steps
Great job! You've learned how to implement Role-Based Access Control in your Node.js applications using Express.js middleware.
- RBAC restricts access based on user roles.
- Middleware functions are ideal for checking roles before route access.
- You can check for single roles or multiple roles.
- Advanced scenarios might involve direct permission checks.
Proper authorization is key to securing your API. Keep practicing to master these concepts!
الأسئلة الشائعة
هل درس «التحكم في الوصول القائم على الأدوار» مجاني؟
نعم — نص درس «التحكم في الوصول القائم على الأدوار» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة Node.js Backend Development Bootcamp، انتقل إلى CoddyKit PRO. تتضمن دورة Node.js Backend Development Bootcamp 6 دروس في المجموع.
ماذا ستتعلم في «التحكم في الوصول القائم على الأدوار»؟
طوّروا برمجيات وسيطة للتفويض، وقيّدوا الوصول إلى مسارات API استنادًا إلى أدوار المستخدمين وأذوناتهم. تتمرن على Node.js Backend Development Bootcamp مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.
هل أحتاج إلى خبرة سابقة لأبدأ Node.js Backend Development Bootcamp؟
لا تُشترط خبرة سابقة. Node.js Backend Development Bootcamp على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 5 من أصل 6.
كم من الوقت يستغرق درس «التحكم في الوصول القائم على الأدوار»؟
معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.
هل يمكنني كتابة وتشغيل أكواد في درس Node.js Backend Development Bootcamp هذا؟
نعم. كل درس في Node.js Backend Development Bootcamp يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.
جميع الدروس في هذه الدورة
- تسجيل المستخدمين وتسجيل الدخول
- إنشاء رموز JWT والتحقق منها
- JWT للمصادقة عديمة الحالة
- دمج تدفق كلمات مرور OAuth2
- التحكم في الوصول القائم على الأدوار
- التحكم في الوصول المستند إلى الأدوار (RBAC)