يعد Bouncer أسلوبًا أنيقًا وغير مقيد بإطار العمل لإدارة الأدوار والقدرات لأي تطبيق يستخدم نماذج Eloquent.
bouncer:clean
يعد Bouncer أسلوبًا أنيقًا وغير مقيد بإطار العمل لإدارة الأدوار والقدرات لأي تطبيق يستخدم نماذج Eloquent. باستخدام بناء جملة معبر وطلاقة، يظل بعيدًا عن طريقك قدر الإمكان: استخدمه عندما تريد، وتجاهله عندما لا تريد ذلك.
للحصول على قائمة سريعة وواضحة لميزات Bouncer، راجع ورقة الغش.
يعمل Bouncer بشكل جيد مع القدرات الأخرى التي قمت بتشفيرها في تطبيقك الخاص. الكود الخاص بك له الأسبقية دائمًا: إذا كان الكود الخاص بك يسمح بإجراء ما، فلن يتدخل Bouncer.
بمجرد التثبيت، يمكنك ببساطة إخبار الحارس بما تريد السماح به عند البوابة:
// Give a user the ability to create posts
Bouncer:: allow ( $ user )-> to ( ' create ' , Post::class);
// Alternatively, do it through a role
Bouncer:: allow ( ' admin ' )-> to ( ' create ' , Post::class);
Bouncer:: assign ( ' admin ' )-> to ( $ user );
// You can also grant an ability only to a specific model
Bouncer:: allow ( $ user )-> to ( ' edit ' , $ post );
عندما تتحقق من قدراتك عند بوابة Laravel، ستتم استشارة Bouncer تلقائيًا. إذا رأى Bouncer القدرة التي تم منحها للمستخدم الحالي (سواء بشكل مباشر أو من خلال دور) فسوف يقوم بتفويض الشيك.
ملاحظة : يتطلب Bouncer v1.0.2 PHP 8.2+ وLaravel/Eloquent 11+.
إذا كنت تستخدم Laravel v6-v10، فاستخدم Bouncer v1.0.1. إذا كنت تستخدم Laravel v5.5-v5.8، فاستخدم Bouncer RC6.
تثبيت الحارس مع الملحن:
composer require silber/bouncer
أضف سمة Bouncer إلى نموذج المستخدم الخاص بك:
use Silber Bouncer Database HasRolesAndAbilities ;
class User extends Model
{
use HasRolesAndAbilities;
}
الآن، لتشغيل عمليات ترحيل Bouncer. قم أولاً بنشر عمليات الترحيل في دليل migrations
في تطبيقك، عن طريق تشغيل الأمر التالي:
php artisan vendor:publish --tag="bouncer.migrations"
أخيرًا، قم بتشغيل عمليات الترحيل:
php artisan migrate
عندما تستخدم واجهة Bouncer
في التعليمات البرمجية الخاصة بك، تذكر إضافة هذا السطر إلى عمليات استيراد مساحة الاسم الخاصة بك في أعلى الملف:
use Bouncer ;
لمزيد من المعلومات حول واجهات Laravel، راجع وثائق Laravel.
تثبيت الحارس مع الملحن:
composer require silber/bouncer
قم بإعداد قاعدة البيانات باستخدام مكون Eloquent Capsule:
use Illuminate Database Capsule Manager as Capsule ;
$ capsule = new Capsule ;
$ capsule -> addConnection ([ /* connection config */ ]);
$ capsule -> setAsGlobal ();
راجع وثائق Eloquent Capsule لمزيد من التفاصيل.
قم بتشغيل عمليات الترحيل بإحدى الطرق التالية:
استخدم أداة مثل vagabond لتشغيل عمليات ترحيل Laravel خارج تطبيق Laravel. ستجد عمليات الترحيل الضرورية في ملف كعب الترحيل.
وبدلاً من ذلك، يمكنك تشغيل SQL الخام مباشرة في قاعدة البيانات الخاصة بك.
أضف سمة Bouncer إلى نموذج المستخدم الخاص بك:
use Illuminate Database Eloquent Model ;
use Silber Bouncer Database HasRolesAndAbilities ;
class User extends Model
{
use HasRolesAndAbilities;
}
إنشاء مثيل Bouncer:
use Silber Bouncer Bouncer ;
$ bouncer = Bouncer:: create ();
// If you are in a request with a current user
// that you'd wish to check permissions for,
// pass that user to the "create" method:
$ bouncer = Bouncer:: create ( $ user );
إذا كنت تستخدم حقن التبعية في تطبيقك، فيمكنك تسجيل مثيل Bouncer
كمثيل فردي في الحاوية:
use Silber Bouncer Bouncer ;
use Illuminate Container Container ;
Container:: getInstance ()-> singleton (Bouncer::class, function () {
return Bouncer:: create ();
});
يمكنك الآن حقن Bouncer
في أي فصل يحتاج إليه.
create
التابع create مثيل Bouncer
بافتراضيات معقولة. لتخصيصه بالكامل، استخدم التابع make
للحصول على نسخة المصنع. قم باستدعاء create()
في المصنع لإنشاء مثيل Bouncer
:
use Silber Bouncer Bouncer ;
$ bouncer = Bouncer:: make ()
-> withCache ( $ customCacheInstance )
-> create ();
قم بإلقاء نظرة على فئة Factory
لرؤية جميع التخصيصات المتاحة.
قم بتعيين النموذج الذي سيتم استخدامه كنموذج المستخدم في تطبيقك:
$ bouncer -> useUserModel (User::class);
للحصول على تكوين إضافي، راجع قسم التكوين أدناه.
افتراضيًا، يتم تخزين استعلامات Bouncer مؤقتًا للطلب الحالي. للحصول على أداء أفضل، قد ترغب في تمكين التخزين المؤقت للطلبات المشتركة.
أصبحت إضافة الأدوار والقدرات للمستخدمين أمرًا سهلاً للغاية. ليس عليك إنشاء دور أو قدرة مقدمًا. ما عليك سوى تمرير اسم الدور/القدرة، وسيقوم Bouncer بإنشائها إذا لم تكن موجودة.
ملاحظة: جميع الأمثلة أدناه تستخدم الواجهة
Bouncer
. إذا كنت لا تستخدم الواجهات، يمكنك بدلاً من ذلك حقن مثيلSilberBouncerBouncer
في فصلك الدراسي.
لنقم بإنشاء دور يسمى admin
ونمنحه القدرة على ban-users
من موقعنا:
Bouncer:: allow ( ' admin ' )-> to ( ' ban-users ' );
هذا كل شيء. خلف الكواليس، سيقوم Bouncer بإنشاء نموذج Role
ونموذج Ability
لك.
إذا كنت تريد إضافة سمات إضافية إلى الدور/القدرة، مثل عنوان يمكن قراءته بواسطة الإنسان، فيمكنك إنشاؤها يدويًا باستخدام توابع role
ability
في فئة Bouncer
:
$ admin = Bouncer:: role ()-> firstOrCreate ([
' name ' => ' admin ' ,
' title ' => ' Administrator ' ,
]);
$ ban = Bouncer:: ability ()-> firstOrCreate ([
' name ' => ' ban-users ' ,
' title ' => ' Ban users ' ,
]);
Bouncer:: allow ( $ admin )-> to ( $ ban );
لمنح دور admin
لمستخدم الآن، ما عليك سوى إخبار الحارس أنه يجب تعيين دور المسؤول للمستخدم المحدد:
Bouncer:: assign ( ' admin ' )-> to ( $ user );
بدلًا من ذلك، يمكنك استدعاء assign
sign مباشرةً على المستخدم:
$ user -> assign ( ' admin ' );
في بعض الأحيان قد ترغب في منح المستخدم قدرة مباشرة، دون استخدام الدور:
Bouncer:: allow ( $ user )-> to ( ' ban-users ' );
هنا أيضًا يمكنك تحقيق نفس الشيء مباشرةً من المستخدم:
$ user -> allow ( ' ban-users ' );
في بعض الأحيان قد ترغب في تقييد القدرة على نوع نموذج معين. ما عليك سوى تمرير اسم النموذج كوسيطة ثانية:
Bouncer:: allow ( $ user )-> to ( ' edit ' , Post::class);
إذا كنت تريد تقييد القدرة على نسخة نموذج معينة، فقم بتمرير النموذج الفعلي بدلاً من ذلك:
Bouncer:: allow ( $ user )-> to ( ' edit ' , $ post );
استخدم التابع toOwn
للسماح للمستخدمين بإدارة نماذجهم الخاصة :
Bouncer:: allow ( $ user )-> toOwn (Post::class);
الآن، عند التحقق عند البوابة مما إذا كان يمكن للمستخدم تنفيذ إجراء ما على منشور معين، ستتم مقارنة user_id
الخاص بالمنشور id
المستخدم الذي قام بتسجيل الدخول (يمكن تخصيص هذا). إذا كانت متطابقة، فإن البوابة تسمح بهذا الإجراء.
ما ورد أعلاه سوف يمنح جميع القدرات على النماذج "المملوكة" للمستخدم. يمكنك تقييد القدرات من خلال متابعتها باستدعاء الأسلوب to
:
Bouncer:: allow ( $ user )-> toOwn (Post::class)-> to ( ' view ' );
// Or pass it an array of abilities:
Bouncer:: allow ( $ user )-> toOwn (Post::class)-> to ([ ' view ' , ' update ' ]);
يمكنك أيضًا السماح للمستخدمين بامتلاك جميع أنواع النماذج في تطبيقك:
Bouncer:: allow ( $ user )-> toOwnEverything ();
// And to restrict ownership to a given ability
Bouncer:: allow ( $ user )-> toOwnEverything ()-> to ( ' view ' );
يمكن للحارس أيضًا سحب الدور المعين مسبقًا من المستخدم:
Bouncer:: retract ( ' admin ' )-> from ( $ user );
أو قم بذلك مباشرة على المستخدم:
$ user -> retract ( ' admin ' );
يمكن للحارس أيضًا إزالة القدرة الممنوحة مسبقًا للمستخدم:
Bouncer:: disallow ( $ user )-> to ( ' ban-users ' );
أو مباشرة على المستخدم:
$ user -> disallow ( ' ban-users ' );
ملاحظة: إذا كان لدى المستخدم دور يسمح له
ban-users
، فسيظل لديه هذه القدرة. ولعدم السماح بذلك، قم بإزالة القدرة من الدور أو سحب الدور من المستخدم.
إذا تم منح القدرة من خلال دور ما، فاطلب من الحارس إزالة القدرة من الدور بدلاً من ذلك:
Bouncer:: disallow ( ' admin ' )-> to ( ' ban-users ' );
لإزالة قدرة نوع نموذج معين، قم بتمرير اسمه كوسيطة ثانية:
Bouncer:: disallow ( $ user )-> to ( ' delete ' , Post::class);
تحذير: إذا كان لدى المستخدم القدرة على
delete
مثيل$post
محدد، فلن يزيل الكود أعلاه هذه القدرة. سيتعين عليك إزالة القدرة بشكل منفصل - عن طريق تمرير$post
الفعلي كوسيطة ثانية - كما هو موضح أدناه.
لإزالة إمكانية لمثيل نموذج معين، قم بتمرير النموذج الفعلي بدلاً من ذلك:
Bouncer:: disallow ( $ user )-> to ( ' delete ' , $ post );
ملاحظة : تقوم طريقة
disallow
فقط بإزالة القدرات التي تم منحها مسبقًا لهذا المستخدم/الدور. إذا كنت تريد عدم السماح بمجموعة فرعية مما تسمح به القدرة العامة، فاستخدم التابعforbid
.
يسمح لك Bouncer أيضًا forbid
قدرة معينة، لمزيد من التحكم الدقيق. في بعض الأحيان، قد ترغب في منح مستخدم/دور قدرة تغطي نطاقًا واسعًا من الإجراءات، ولكن بعد ذلك تقوم بتقييد مجموعة فرعية صغيرة من تلك الإجراءات.
فيما يلي بعض الأمثلة:
قد تسمح للمستخدم بعرض جميع المستندات بشكل عام، ولكن لديك مستند محدد عالي السرية لا ينبغي السماح له بعرضه:
Bouncer:: allow ( $ user )-> to ( ' view ' , Document::class);
Bouncer:: forbid ( $ user )-> to ( ' view ' , $ classifiedDocument );
قد ترغب في السماح للمسؤولين superadmin
لديك بالقيام بكل شيء في تطبيقك، بما في ذلك إضافة/إزالة المستخدمين. بعد ذلك، قد يكون لديك دور admin
يمكنه القيام بكل شيء إلى جانب إدارة المستخدمين:
Bouncer:: allow ( ' superadmin ' )-> everything ();
Bouncer:: allow ( ' admin ' )-> everything ();
Bouncer:: forbid ( ' admin ' )-> toManage (User::class);
قد ترغب في حظر المستخدمين من حين لآخر، وإزالة إذنهم لجميع القدرات. ومع ذلك، فإن إزالة جميع أدوارهم وقدراتهم في الواقع يعني أنه عند إزالة الحظر، سيتعين علينا معرفة أدوارهم وقدراتهم الأصلية.
استخدام القدرة المحرمة يعني أنه يمكنهم الاحتفاظ بجميع أدوارهم وقدراتهم الحالية، ولكن لا يزال غير مسموح لهم بأي شيء. يمكننا تحقيق ذلك عن طريق إنشاء دور خاص banned
، والذي سنمنع كل شيء فيه:
Bouncer:: forbid ( ' banned ' )-> everything ();
بعد ذلك، عندما نريد حظر مستخدم، سنقوم بتعيين الدور banned
له:
Bouncer:: assign ( ' banned ' )-> to ( $ user );
لإزالة الحظر، سنقوم ببساطة بسحب الدور من المستخدم:
Bouncer:: retract ( ' banned ' )-> from ( $ user );
كما ترون، تمنحك القدرات المحظورة لـ Bouncer قدرًا كبيرًا من التحكم الدقيق في الأذونات الموجودة في تطبيقك.
لإزالة قدرة محظورة، استخدم الطريقة unforbid
:
Bouncer:: unforbid ( $ user )-> to ( ' view ' , $ classifiedDocument );
ملحوظة : سيؤدي هذا إلى إزالة أي قدرة محظورة مسبقًا. لن يسمح تلقائيًا بالقدرة إذا لم تكن مسموحة بها بالفعل من خلال قدرة عادية مختلفة ممنوحة لهذا المستخدم/الدور.
ملاحظة : بشكل عام، لا ينبغي أن تحتاج إلى التحقق من الأدوار مباشرة. من الأفضل السماح بدور معين بقدرات معينة، ثم التحقق من تلك القدرات بدلاً من ذلك. إذا كان ما تحتاجه عامًا جدًا، فيمكنك إنشاء قدرات واسعة جدًا. على سبيل المثال، تعد القدرة
access-dashboard
دائمًا أفضل من التحقق من أدوارadmin
أوeditor
مباشرةً. في المناسبات النادرة التي تريد فيها التحقق من أحد الأدوار، تتوفر هذه الوظيفة هنا.
يمكن للحارس التحقق مما إذا كان لدى المستخدم دور محدد:
Bouncer:: is ( $ user )-> a ( ' moderator ' );
إذا كان الدور الذي تتحقق منه يبدأ بحرف متحرك، فقد ترغب في استخدام التابع an
:
Bouncer:: is ( $ user )-> an ( ' admin ' );
بالنسبة للعكس، يمكنك أيضًا التحقق مما إذا كان المستخدم ليس لديه دور محدد:
Bouncer:: is ( $ user )-> notA ( ' moderator ' );
Bouncer:: is ( $ user )-> notAn ( ' admin ' );
يمكنك التحقق مما إذا كان لدى المستخدم أحد الأدوار العديدة:
Bouncer:: is ( $ user )-> a ( ' moderator ' , ' editor ' );
يمكنك أيضًا التحقق مما إذا كان المستخدم لديه جميع الأدوار المحددة:
Bouncer:: is ( $ user )-> all ( ' editor ' , ' moderator ' );
يمكنك أيضًا التحقق مما إذا كان المستخدم ليس لديه أي من الأدوار المحددة:
Bouncer:: is ( $ user )-> notAn ( ' editor ' , ' moderator ' );
يمكن أيضًا إجراء هذه الفحوصات مباشرة على المستخدم:
$ user -> isAn ( ' admin ' );
$ user -> isA ( ' subscriber ' );
$ user -> isNotAn ( ' admin ' );
$ user -> isNotA ( ' subscriber ' );
$ user -> isAll ( ' editor ' , ' moderator ' );
يمكنك الاستعلام عن المستخدمين لديك لمعرفة ما إذا كان لديهم دور معين:
$ users = User:: whereIs ( ' admin ' )-> get ();
يمكنك أيضًا تمرير أدوار متعددة للاستعلام عن المستخدمين الذين لديهم أي من الأدوار المحددة:
$ users = User:: whereIs ( ' superadmin ' , ' admin ' )-> get ();
للاستعلام عن المستخدمين الذين لديهم جميع الأدوار المحددة، استخدم التابع whereIsAll
:
$ users = User:: whereIsAll ( ' sales ' , ' marketing ' )-> get ();
يمكنك الحصول على جميع الأدوار للمستخدم مباشرة من نموذج المستخدم:
$ roles = $ user -> getRoles ();
يمكنك الحصول على كافة القدرات للمستخدم مباشرة من نموذج المستخدم:
$ abilities = $ user -> getAbilities ();
سيؤدي هذا إلى إرجاع مجموعة من القدرات المسموح بها للمستخدم، بما في ذلك أي قدرات ممنوحة للمستخدم من خلال أدواره.
يمكنك أيضًا الحصول على قائمة بالقدرات التي تم حظرها بشكل صريح :
$ forbiddenAbilities = $ user -> getForbiddenAbilities ();
يتم التعامل مع تخويل المستخدمين مباشرة في Laravel's Gate
، أو في نموذج المستخدم ( $user->can($ability)
).
من أجل الراحة، توفر فئة Bouncer
طرق العبور التالية:
Bouncer:: can ( $ ability );
Bouncer:: can ( $ ability , $ model );
Bouncer:: canAny ( $ abilities );
Bouncer:: canAny ( $ abilities , $ model );
Bouncer:: cannot ( $ ability );
Bouncer:: cannot ( $ ability , $ model );
Bouncer:: authorize ( $ ability );
Bouncer:: authorize ( $ ability , $ model );
يتم استدعاؤها مباشرةً إلى الأساليب المكافئة لها في فئة Gate
.
لا يضيف Bouncer توجيهات الشفرة الخاصة به. نظرًا لأن Bouncer يعمل مباشرة مع بوابة Laravel، فما عليك سوى استخدام التوجيه @can
الخاص به للتحقق من قدرات المستخدم الحالي:
@can ('update', $post)
< a href =" {{ route('post.update', $post) }} " > Edit Post </ a >
@endcan
نظرًا لأنه لا يوصى عمومًا بالتحقق من الأدوار مباشرةً، فإن Bouncer لا يأتي مع توجيه منفصل لذلك. إذا كنت لا تزال مصرًا على التحقق من الأدوار، فيمكنك القيام بذلك باستخدام التوجيه @if
العام:
@ if ( $ user -> isAn ( ' admin ' ))
//
@endif
يتم تخزين كافة الاستعلامات التي يتم تنفيذها بواسطة Bouncer مؤقتًا للطلب الحالي. إذا قمت بتمكين التخزين المؤقت للطلبات المشتركة، فستستمر ذاكرة التخزين المؤقت عبر الطلبات المختلفة.
متى شئت، يمكنك تحديث ذاكرة التخزين المؤقت للحارس بالكامل:
Bouncer:: refresh ();
ملاحظة: يؤدي تحديث ذاكرة التخزين المؤقت بالكامل لجميع المستخدمين إلى استخدام علامات ذاكرة التخزين المؤقت إذا كانت متوفرة. ليست كل برامج تشغيل ذاكرة التخزين المؤقت تدعم هذا. ارجع إلى وثائق Laravel لمعرفة ما إذا كان برنامج التشغيل الخاص بك يدعم علامات ذاكرة التخزين المؤقت. إذا كان برنامج التشغيل الخاص بك لا يدعم علامات ذاكرة التخزين المؤقت، فقد يكون استدعاء
refresh
بطيئًا بعض الشيء، اعتمادًا على عدد المستخدمين في نظامك.
وبدلاً من ذلك، يمكنك تحديث ذاكرة التخزين المؤقت لمستخدم محدد فقط:
Bouncer:: refreshFor ( $ user );
ملاحظة : عند استخدام نطاقات متعددة الإيجار، سيؤدي هذا فقط إلى تحديث ذاكرة التخزين المؤقت للمستخدم في سياق النطاق الحالي. لمسح البيانات المخزنة مؤقتًا لنفس المستخدم في سياق نطاق مختلف، يجب استدعاؤها من داخل هذا النطاق.
يدعم Bouncer بشكل كامل التطبيقات متعددة المستأجرين، مما يسمح لك بدمج أدوار وقدرات Bouncer لجميع المستأجرين بسلاسة داخل التطبيق نفسه.
للبدء، قم أولاً بنشر البرنامج الوسيط للنطاق في تطبيقك:
php artisan vendor:publish --tag="bouncer.middleware"
سيتم الآن نشر البرنامج الوسيط على app/Http/Middleware/ScopeBouncer.php
. هذه البرامج الوسيطة هي المكان الذي تخبر فيه Bouncer بالمستأجر الذي يجب استخدامه للطلب الحالي. على سبيل المثال، بافتراض أن جميع المستخدمين لديهم سمة account_id
، فهذا هو الشكل الذي ستبدو عليه برمجيتك الوسيطة:
public function handle ( $ request , Closure $ next )
{
$ tenantId = $ request -> user ()-> account_id ;
Bouncer:: scope ()-> to ( $ tenantId );
return $ next ( $ request );
}
أنت بالطبع حر في تعديل هذه البرامج الوسيطة لتناسب احتياجات تطبيقك، مثل سحب معلومات المستأجر من نطاق فرعي وما إلى ذلك.
الآن بعد أن تم تثبيت البرنامج الوسيط، تأكد من تسجيله في HTTP Kernel الخاص بك:
protected $ middlewareGroups = [
' web ' => [
// Keep the existing middleware here, and add this:
App Http Middleware ScopeBouncer::class,
]
];
سيتم الآن توجيه جميع استفسارات Bouncer إلى المستأجر المحدد.
اعتمادًا على إعداد التطبيق الخاص بك، قد لا ترغب في الواقع في أن يتم تحديد نطاق كافة الاستعلامات للمستأجر الحالي. على سبيل المثال، قد يكون لديك مجموعة ثابتة من الأدوار/القدرات التي تكون متماثلة لجميع المستأجرين، وتسمح فقط لمستخدميك بالتحكم في المستخدمين الذين تم تعيينهم للأدوار، والأدوار التي تتمتع بالقدرات. لتحقيق ذلك، يمكنك إخبار نطاق Bouncer بنطاق العلاقات بين نماذج Bouncer فقط، وليس النماذج نفسها:
Bouncer:: scope ()-> to ( $ tenantId )-> onlyRelations ();
علاوة على ذلك، قد لا يسمح تطبيقك لمستخدميه بالتحكم في القدرات التي يتمتع بها دور معين. في هذه الحالة، اطلب من نطاق Bouncer استبعاد قدرات الأدوار من النطاق، بحيث تظل هذه العلاقات عالمية عبر جميع المستأجرين:
Bouncer:: scope ()-> to ( $ tenantId )-> onlyRelations ()-> dontScopeRoleAbilities ();
إذا كانت احتياجاتك أكثر تخصصًا مما هو مذكور أعلاه، فيمكنك إنشاء Scope
الخاص بك باستخدام أي منطق مخصص تحتاجه:
use Silber Bouncer Contracts Scope ;
class MyScope implements Scope
{
// Whatever custom logic your app needs
}
ثم، في مزود الخدمة، قم بتسجيل النطاق المخصص الخاص بك:
Bouncer:: scope ( new MyScope );
سوف يقوم Bouncer باستدعاء الأساليب الموجودة على واجهة Scope
في نقاط مختلفة أثناء تنفيذها. أنت حر في التعامل معها وفقًا لاحتياجاتك الخاصة.
يأتي Bouncer مزودًا بافتراضيات معقولة، لذلك في معظم الأوقات لن تكون هناك حاجة لأي تكوين. للتحكم بشكل أكثر دقة، يمكن تخصيص Bouncer عن طريق استدعاء طرق التكوين المختلفة في فئة Bouncer
.
إذا كنت تستخدم واحدًا أو اثنين فقط من خيارات التكوين هذه، فيمكنك لصقها في طريقة boot
الرئيسية لـ AppServiceProvider
. إذا بدأوا في النمو، فيمكنك إنشاء فئة BouncerServiceProvider
منفصلة في دليل app/Providers
(تذكر تسجيله في مصفوفة تكوين providers
).
افتراضيًا، يتم تخزين كافة الاستعلامات التي يتم تنفيذها بواسطة Bouncer مؤقتًا للطلب الحالي. للحصول على أداء أفضل، قد ترغب في استخدام التخزين المؤقت للطلبات المشتركة:
Bouncer:: cache ();
تحذير: إذا قمت بتمكين التخزين المؤقت للطلبات المشتركة، فأنت مسؤول عن تحديث ذاكرة التخزين المؤقت كلما قمت بإجراء تغييرات على أدوار/قدرات المستخدم. لمعرفة كيفية تحديث ذاكرة التخزين المؤقت، اقرأ تحديث ذاكرة التخزين المؤقت.
على العكس من ذلك، قد ترغب في بعض الأحيان في تعطيل ذاكرة التخزين المؤقت بشكل كامل ، حتى ضمن نفس الطلب:
Bouncer:: dontCache ();
يعد هذا مفيدًا بشكل خاص في اختبارات الوحدة، عندما تريد تشغيل التأكيدات ضد الأدوار/القدرات التي تم منحها للتو.
لتغيير أسماء جداول قاعدة البيانات التي يستخدمها Bouncer، قم بتمرير مصفوفة اقترانية إلى التابع tables
. يجب أن تكون المفاتيح هي أسماء الجداول الافتراضية لـ Bouncer، ويجب أن تكون القيم هي أسماء الجداول التي ترغب في استخدامها. ليس عليك تمرير أسماء كافة الجداول؛ فقط تلك التي ترغب في تغييرها.
Bouncer:: tables ([
' abilities ' => ' my_abilities ' ,
' permissions ' => ' granted_abilities ' ,
]);
يستخدم الترحيل المنشور لـ Bouncer أسماء الجداول من هذا التكوين، لذا تأكد من وجودها في مكانها قبل تشغيل الترحيل فعليًا.
يمكنك بسهولة توسيع نماذج Role
Ability
المضمنة في Bouncer:
namespace App Models ;
use Silber Bouncer Database Ability as BouncerAbility ;
class Ability extends BouncerAbility
{
// custom code
}
namespace App Models ;
use Silber Bouncer Database Role as BouncerRole ;
class Role extends BouncerRole
{
// custom code
}
بدلًا من ذلك، يمكنك استخدام سمات IsAbility
و IsRole
الخاصة بـ Bouncer دون توسيع أي من نماذج Bouncer فعليًا:
namespace App Models ;
use Illuminate Database Eloquent Model ;
use Silber Bouncer Database Concerns IsAbility ;
class Ability extends Model
{
use IsAbility;
// custom code
}
namespace App Models ;
use Illuminate Database Eloquent Model ;
use Silber Bouncer Database Concerns IsRole ;
class Role extends Model
{
use IsRole;
// custom code
}
إذا كنت تستخدم السمات بدلاً من توسيع نماذج Bouncer، فتأكد من تعيين اسم $table
المناسب والحقول $fillable
بنفسك.
بغض النظر عن الطريقة التي تستخدمها، فإن الخطوة التالية هي إخبار Bouncer فعليًا باستخدام نماذجك المخصصة:
Bouncer:: useAbilityModel ( App Models Ability::class);
Bouncer:: useRoleModel ( App Models Role::class);
ملحوظة : يحدد Eloquent المفتاح الخارجي للعلاقات بناءً على اسم النموذج الأصلي (راجع مستندات Eloquent). لتبسيط الأمور، قم بتسمية فئاتك المخصصة بنفس اسم Bouncer:
Ability
Role
، على التوالي.إذا كنت بحاجة إلى استخدام أسماء مختلفة، فتأكد من تحديث ملف الترحيل الخاص بك أو تجاوز طرق العلاقة لتعيين مفاتيحها الخارجية بشكل صريح.
افتراضيًا، يستخدم Bouncer تلقائيًا نموذج المستخدم الخاص بحارس المصادقة الافتراضي.
إذا كنت تستخدم Bouncer مع حارس غير افتراضي، ويستخدم نموذج مستخدم مختلفًا، فيجب عليك إعلام Bouncer بنموذج المستخدم الذي تريد استخدامه:
Bouncer:: useUserModel ( App Admin::class);
في الحارس، يتم استخدام مفهوم الملكية للسماح للمستخدمين بتنفيذ إجراءات على النماذج التي "يمتلكونها".
افتراضيًا، سيقوم Bouncer بالتحقق من user_id
الخاص بالنموذج مقابل المفتاح الأساسي للمستخدم الحالي. إذا لزم الأمر، يمكن تعيين هذا إلى سمة مختلفة:
Bouncer:: ownedVia ( ' userId ' );
إذا كانت النماذج المختلفة تستخدم أعمدة مختلفة للملكية، فيمكنك تسجيلها بشكل منفصل:
Bouncer:: ownedVia (Post::class, ' created_by ' );
Bouncer:: ownedVia (Order::class, ' entered_by ' );
لمزيد من التحكم، يمكنك تمرير الإغلاق باستخدام المنطق المخصص الخاص بك:
Bouncer:: ownedVia (Game::class, function ( $ game , $ user ) {
return $ game -> team_id == $ user -> team_id ;
});
هناك بعض المفاهيم في Bouncer التي يستمر الأشخاص في السؤال عنها، لذا إليك قائمة قصيرة ببعض هذه المواضيع:
يمكن القيام ببذر الأدوار والقدرات الأولية في فصل بذر Laravel العادي. ابدأ بإنشاء ملف بذارة محدد لـ Bouncer:
php artisan make:seeder BouncerSeeder
ضع جميع أدوار البذر وأكواد القدرات الخاصة بك في طريقة run
البذارة. فيما يلي مثال لما قد يبدو عليه الأمر:
use Bouncer ;
use Illuminate Database Seeder ;
class BouncerSeeder extends Seeder
{
public function run ()
{
Bouncer:: allow ( ' superadmin ' )-> everything ();
Bouncer:: allow ( ' admin ' )-> everything ();
Bouncer:: forbid ( ' admin ' )-> toManage (User::class);
Bouncer:: allow ( ' editor ' )-> to ( ' create ' , Post::class);
Bouncer:: allow ( ' editor ' )-> toOwn (Post::class);
// etc.
}
}
لتشغيله فعليًا، قم بتمرير اسم فئة المُزارع إلى خيار class
الخاص بالأمر db:seed
:
php artisan db:seed --class=BouncerSeeder
يمكن استخدام scope
Bouncer لتقسيم أجزاء مختلفة من الموقع، وإنشاء صومعة لكل منها مع مجموعة الأدوار والقدرات الخاصة به:
قم بإنشاء برنامج وسيط ScopeBouncer
الذي يأخذ $identifier
ويقوم بتعيينه كنطاق حالي:
use Bouncer , Closure ;
class ScopeBouncer
{
public function handle ( $ request , Closure $ next , $ identifier )
{
Bouncer:: scope ()-> to ( $ identifier );
return $ next ( $ request );
}
}
قم بتسجيل هذه البرامج الوسيطة الجديدة كبرامج وسيطة للمسار في فئة HTTP Kernel الخاصة بك:
protected $ routeMiddleware = [
// Keep the other route middleware, and add this:
' scope-bouncer ' => App Http Middleware ScopeBouncer::class,
];
في مزود خدمة المسار الخاص بك، قم بتطبيق هذه البرامج الوسيطة بمعرف مختلف للمسارات العامة ومسارات لوحة المعلومات، على التوالي:
Route:: middleware ([ ' web ' , ' scope-bouncer:1 ' ])
-> namespace ( $ this -> namespace )
-> group ( base_path ( ' routes/public.php ' ));
Route:: middleware ([ ' web ' , ' scope-bouncer:2 ' ])
-> namespace ( $ this -> namespace )
-> group ( base_path ( ' routes/dashboard.php ' ));
هذا كل شيء. سيتم الآن تحديد نطاق جميع الأدوار والقدرات بشكل منفصل لكل قسم من موقعك. لضبط نطاق النطاق، راجع تخصيص نطاق الحارس.
بدءًا من Laravel 5.4، أصبحت مجموعة أحرف قاعدة البيانات الافتراضية الآن utf8mb4
. إذا كنت تستخدم إصدارات أقدم من بعض قواعد البيانات (MySQL أقل من 5.7.7، أو MariaDB أقل من 10.2.2) مع Laravel 5.4+، فسوف تحصل على خطأ SQL عند محاولة إنشاء فهرس على عمود سلسلة. لإصلاح ذلك، قم بتغيير طول سلسلة Laravel الافتراضية في AppServiceProvider
الخاص بك:
use Illuminate Support Facades Schema ;
public function boot ()
{
Schema:: defaultStringLength ( 191 );
}
يمكنك قراءة المزيد في مقالة Laravel News هذه.
تعد أعمدة JSON إضافة جديدة نسبيًا إلى MySQL (5.7.8) وMariaDB (10.2.7). إذا كنت تستخدم إصدارًا أقدم من قواعد البيانات هذه، فلا يمكنك استخدام أعمدة JSON.
الحل الأفضل هو ترقية قاعدة بياناتك. إذا لم يكن ذلك ممكنًا حاليًا، فيمكنك تغيير ملف الترحيل المنشور لاستخدام عمود text
بدلاً من ذلك:
- $table->json('options')->nullable();
+ $table->text('options')->nullable();
bouncer:clean
bouncer:clean
بحذف القدرات غير المستخدمة. سيؤدي تشغيل هذا الأمر إلى حذف نوعين من القدرات غير المستخدمة:
القدرات غير المخصصة - القدرات التي لم يتم تخصيصها لأي شخص. على سبيل المثال:
Bouncer:: allow ( $ user )-> to ( ' view ' , Plan::class);
Bouncer:: disallow ( $ user )-> to ( ' view ' , Plan::class);
في هذه المرحلة، لا يتم تخصيص إمكانية "عرض الخطط" لأي شخص، لذا سيتم حذفها.
ملاحظة : اعتمادًا على سياق تطبيقك، قد لا ترغب في حذفها. إذا سمحت للمستخدمين بإدارة القدرات في واجهة مستخدم تطبيقك، فربما لا ترغب في حذف القدرات غير المخصصة. انظر أدناه.
القدرات المعزولة - قدرات النموذج التي تم حذف نماذجها:
Bouncer:: allow ( $ user )-> to ( ' delete ' , $ plan );
$ plan -> delete ();
وبما أن الخطة لم تعد موجودة، فإن القدرة لم تعد ذات فائدة، لذلك سيتم حذفها.
إذا كنت تريد حذف نوع واحد فقط من القدرات غير المستخدمة، فقم بتشغيله باستخدام إحدى العلامات التالية:
php artisan bouncer:clean --unassigned
php artisan bouncer:clean --orphaned
إذا لم تقم بتمرير أي إشارات إليه، فسيتم حذف كلا النوعين من القدرات غير المستخدمة.
لتشغيل هذا الأمر تلقائيًا بشكل دوري، قم بإضافته إلى جدول kernel لوحدة التحكم الخاصة بك:
$ schedule -> command ( ' bouncer:clean ' )-> weekly ();
// Adding abilities for users
Bouncer:: allow ( $ user )-> to ( ' ban-users ' );
Bouncer:: allow ( $ user )-> to ( ' edit ' , Post::class);
Bouncer:: allow ( $ user )-> to ( ' delete ' , $ post );
Bouncer:: allow ( $ user )-> everything ();
Bouncer:: allow ( $ user )-> toManage (Post::class);
Bouncer:: allow ( $ user )-> toManage ( $ post );
Bouncer:: allow ( $ user )-> to ( ' view ' )-> everything ();
Bouncer:: allow ( $ user )-> toOwn (Post::class);
Bouncer:: allow ( $ user )-> toOwnEverything ();
// Removing abilities uses the same syntax, e.g.
Bouncer:: disallow ( $ user )-> to ( ' delete ' , $ post );
Bouncer:: disallow ( $ user )-> toManage (Post::class);
Bouncer:: disallow ( $ user )-> toOwn (Post::class);
// Adding & removing abilities for roles
Bouncer:: allow ( ' admin ' )-> to ( ' ban-users ' );
Bouncer:: disallow ( ' admin ' )-> to ( ' ban-users ' );
// You can also forbid specific abilities with the same syntax...
Bouncer:: forbid ( $ user )-> to ( ' delete ' , $ post );
// And also remove a forbidden ability with the same syntax...
Bouncer:: unforbid ( $ user )-> to ( ' delete ' , $ post );
// Re-syncing a user's abilities
Bouncer:: sync ( $ user )-> abilities ( $ abilities );
// Assigning & retracting roles from users
Bouncer:: assign ( ' admin ' )-> to ( $ user );
Bouncer:: retract ( ' admin ' )-> from ( $ user );
// Assigning roles to multiple users by ID
Bouncer:: assign ( ' admin ' )-> to ([ 1 , 2 , 3 ]);
// Re-syncing a user's roles
Bouncer:: sync ( $ user )-> roles ( $ roles );
// Checking the current user's abilities
$ boolean = Bouncer:: can ( ' ban-users ' );
$ boolean = Bouncer:: can ( ' edit ' , Post::class);
$ boolean = Bouncer:: can ( ' delete ' , $ post );
$ boolean = Bouncer:: cannot ( ' ban-users ' );
$ boolean = Bouncer:: cannot ( ' edit ' , Post::class);
$ boolean = Bouncer:: cannot ( ' delete ' , $ post );
// Checking a user's roles
$ boolean = Bouncer:: is ( $ user )-> a ( ' subscriber ' );
$ boolean = Bouncer:: is ( $ user )-> an ( ' admin ' );
$ boolean = Bouncer:: is ( $ user )-> notA ( ' subscriber ' );
$ boolean = Bouncer:: is ( $ user )-> notAn ( ' admin ' );
$ boolean = Bouncer:: is ( $ user )-> a ( ' moderator ' , ' editor ' );
$ boolean = Bouncer:: is ( $ user )-> all ( ' moderator ' , ' editor ' );
Bouncer:: cache ();
Bouncer:: dontCache ();
Bouncer:: refresh ();
Bouncer:: refreshFor ( $ user );
بعض هذه الوظائف متاحة أيضًا مباشرةً في نموذج المستخدم:
$ user -> allow ( ' ban-users ' );
$ user -> allow ( ' edit ' , Post::class);
$ user -> allow ( ' delete ' , $ post );
$ user -> disallow ( ' ban-users ' );
$ user -> disallow ( ' edit ' , Post::class);
$ user -> disallow ( ' delete ' , $ post );
$ user -> assign ( ' admin ' );
$ user -> retract ( ' admin ' );
$ boolean = $ user -> isAn ( ' admin ' );
$ boolean = $ user -> isAn ( ' editor ' , ' moderator ' );
$ boolean = $ user -> isAll ( ' moderator ' , ' editor ' );
$ boolean = $ user -> isNotAn ( ' admin ' , ' moderator ' );
// Querying users by their roles
$ users = User:: whereIs ( ' superadmin ' )-> get ();
$ users = User:: whereIs ( ' superadmin ' , ' admin ' )-> get ();
$ users = User:: whereIsAll ( ' sales ' , ' marketing ' )-> get ();
$ abilities = $ user -> getAbilities ();
$ forbidden = $ user -> getForbiddenAbilities ();
من بين حزم باجيليون التي منحها Spatie للمجتمع بكل لطف، ستجد حزمة أذونات Laravel الممتازة. مثل Bouncer، فهو يتكامل بشكل جيد مع البوابة المدمجة في Laravel والتحقق من الأذونات، ولكنه يحتوي على مجموعة مختلفة من خيارات التصميم عندما يتعلق الأمر بالتركيب وبنية قاعدة البيانات وميزاتها.
Bouncer هو برنامج مفتوح المصدر مرخص بموجب ترخيص MIT