يعد 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:
AbilityRole، على التوالي.إذا كنت بحاجة إلى استخدام أسماء مختلفة، فتأكد من تحديث ملف الترحيل الخاص بك أو تجاوز طرق العلاقة لتعيين مفاتيحها الخارجية بشكل صريح.
افتراضيًا، يستخدم 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