NestJS — Node.js للمؤسسات

التفويض المتقدّم: السياسات و CASL

18 دقيقة الدرس 30 من 30

التفويض المتقدّم: السياسات و CASL

يُجيب RBAC عن "هل لهذا المستخدم دور المدير؟" لكنّ التطبيقات الحقيقية تحتاج قواعد أدقّ: "هل يستطيع هذا المستخدم تعديل هذا المقال تحديدًا؟" يعتمد ذلك على المستخدم والإجراء والمورد معًا. تعالج المصادقة القائمة على السياسات (أو السمات) هذا، وCASL أشهر مكتبة لها في عالم NestJS.

لماذا لا يكفي RBAC

تأمّل تعديل مقال. القاعدة "يستطيع المستخدم تعديل مقال ألّفه، أو أي مقال إن كان مديرًا". لا يستطيع RBAC الصرف التعبير عن نصف الملكية — فالقرار يعتمد على مقارنة المستخدم بالمورد. وهنا تتألّق السياسات.

تعريف القدرات بـ CASL

يصف CASL الصلاحيات كـ قدرات (abilities): تركيبات من إجراء (read أو update أو delete) وموضوع (نموذج)، اختياريًا بشروط:

import { AbilityBuilder, createMongoAbility } from '@casl/ability'; function defineAbilitiesFor(user) { const { can, cannot, build } = new AbilityBuilder(createMongoAbility); if (user.isAdmin) { can('manage', 'all'); // المديرون يفعلون كل شيء } else { can('read', 'Article'); // أي أحد يقرأ المقالات can('update', 'Article', { authorId: user.id }); // منشوره فقط } return build(); }

manage وall رمزان شاملان في CASL يعنيان "أي إجراء" و"أي موضوع". والشرط { authorId: user.id } هو قاعدة الملكية التي لم يستطع RBAC التعبير عنها.

فحص قدرة

const ability = defineAbilitiesFor(currentUser); if (ability.can('update', article)) { // مسموح — إمّا يملك هذا المقال، أو هو مدير } else { throw new ForbiddenException(); }
الفحص واعٍ بالمورد. تُقيّم ability.can('update', article) الشرط مقابل نسخة المقال الفعلية — مقارنةً authorId بالمستخدم. تلك هي القفزة وراء فحوص الأدوار.

التكامل مع NestJS

النمط الاصطلاحي مزوّد CaslAbilityFactory يبني القدرات لمستخدم، إضافةً إلى حارس سياسات يُقيّم سياسة مُعلَنة. يُرفِق مُزخرِف @CheckPolicies() القاعدةَ، ويفرضها الحارس:

@UseGuards(AuthGuard('jwt'), PoliciesGuard) @CheckPolicies((ability) => ability.can('update', 'Article')) @Patch(':id') update(@Param('id') id: string) {}

اختيار النموذج الصحيح

  • RBAC — بوّابات أدوار بسيطة ("المديرون فقط"). استخدمه حين تتطابق الصلاحيات بنظافة مع الأدوار.
  • السياسات/ABAC (CASL) — قواعد تتضمّن ملكية أو شروطًا أو سمات مورد. استخدمه حين "يعتمد الأمر على المورد".
ادمجهما. تستخدم معظم تطبيقات الإنتاج RBAC للبوّابات الخشنة (هل هذه منطقة مدير؟) والسياسات للفحوص الدقيقة الواعية بالملكية (هل يستطيع هذا المستخدم لمس هذا السجلّ؟). فهما متكاملان لا متنافسان.
افرض التفويض دائمًا على الخادم. إخفاء زرّ في الواجهة ليس أمانًا — يجب أن تعمل فحوص القدرة ذاتها في حُرّاسك/خدماتك. يستطيع عميل مُصِرّ استدعاء أي نقطة نهاية مباشرة، فالخادم هو المكان الوحيد الذي يهمّ فيه التفويض فعلًا.

الخلاصة

تُعبّر المصادقة القائمة على السياسات (بـ CASL) عن قواعد تعتمد على الإجراء والموضوع وشروط المورد — كتعديل محتواك فقط — وهو ما لا يستطيعه RBAC. عرّف القدرات بـ can/cannot، وافحصها بوعي بالمورد عبر ability.can(action, resource)، وادمجها عبر حارس سياسات و@CheckPolicies(). استخدم RBAC للأدوار الخشنة والسياسات لقواعد الملكية الدقيقة. بهذا تكتمل المرحلة السادسة — صارت واجهاتك مُصادَقة ومُفوَّضة كما ينبغي. تاليًا: تصميم API.

اكتمل الدرس!

تهانينا! لقد أكملت جميع الدروس في هذا البرنامج التعليمي.