کار با پکیج Spatie Role-Permission در لاراول

در این پست قراره که به صورت کامل کار با پکیج Role Permission توضیح بدیم و مثال های واقعی در دل لاراول بزنیم. در ابتدا این پکیج توضیح میدیم و مزایا آن رو میگیم و بعد شروع به کار عملی با اون میکنیم.

پکیج Role-Permission چیه؟

پکیج Spatie Laravel Permission یکی از پکیج‌های معروف و قدرتمند در لاراول است که برای مدیریت نقش‌ها (Roles) و مجوزها (Permissions) در برنامه‌های لاراولی استفاده می‌شود. این پکیج به شما اجازه می‌دهد تا به سادگی سیستم دسترسی به منابع و عملیات مختلف را مدیریت کنید. شما به راحتی میتونید به کاربران خود هر دسترسی و مجوز خاص بدید و بر اساس اون مجوز ها کاربران قادر به انجام کار های مختلفی میکنند.

برای مثال: فرض کنید شما توسعه دهنده کد نیوز هستید و برای بخش نویسندگان میخواهید یک سری قوانین بزارید که مثلا فقط کاربران نویسنده به اون صفحه دسترسی داشته باشند، شما میتونید با استفاده از این پکیج بگید که کسایی که مجوز نویسندگی دارند قادر به دیدن این صفحه باشند.

ویژگی‌های اصلی پکیج Spatie Laravel Permission:

  1. مدیریت نقش‌ها و مجوزها: با استفاده از این پکیج می‌توانید نقش‌ها و مجوزهای مختلفی تعریف کنید و آنها را به کاربران مختلف اختصاص دهید.
  2. گروه‌بندی مجوزها در نقش‌ها: می‌توانید مجوزها را به نقش‌ها نسبت دهید و به این ترتیب، همه کاربران با یک نقش خاص دسترسی به مجموعه‌ای از مجوزها داشته باشند.
  3. نقش‌ها و مجوزها به کاربران: به راحتی می‌توانید به هر کاربر نقش‌ها و مجوزهای خاصی اختصاص دهید.
  4. چک کردن دسترسی کاربران: با استفاده از متدهای این پکیج، می‌توانید به سادگی بررسی کنید که آیا کاربری مجوز خاصی دارد یا خیر.
  5. پشتیبانی از چک کردن دسترسی‌ها در Blade templates و Gate ها: شما می‌توانید به راحتی دسترسی‌ها را در قالب‌ها و کنترلرها بررسی کنید.

نصب پکیج

1.برای نصب پکیج خیلی راحت میتونید با استفاده از composer پکیج نصب کنید، برای نصب دستور زیر کپی و در ترمینال خودتون پیست کنید:

composer require spatie/laravel-permission

2. بعد از نصب شما باید فایل های config و migration های پکیج publish کنید:

php artisan vendor:publish --provider="SpatiePermissionPermissionServiceProvider"

3. اگر از uuid استفاده میکنید باید در فایل کانفیگ که در "configpermission.php" قرار دارد کلید "model_morph_key" ویرایش کنید و یک uuid بهش اضافه کنید:

'model_morph_key' => 'model_id',   ❌
'model_morph_key' => 'model_uuid', ✅

4. اگر از قابلیت تیم استفاده میکنید باید در فایل کانفیگ کلید تیم فعال کنید.

5. سعی کنید کش رو پاک کنید برای اطمینان بیشتر و اعمال تغییراتی که دادید:

php artisan optimize:clear

6. حالا نیازه که شما migration ها migrate کنید:

php artisan migrate

7. در مرحله آخر شما نیاز دارید که تریت به نام HasRoles به مدل User اضافه کنید:

use IlluminateDatabaseEloquentModel;
use SpatiePermissionTraitsHasRoles;

class User extends Model
{
    use HasRoles;

    ...
}

مکانیزم پکیج

برای اینکه بدونید این پکیج دقیقا چه کاری انجام میده میخوام وارد جزئیاتش بشم تا کامل متوجه کاری که میکنید بشید. ما در نرم افزار ها بسیاری مجوز یا همون permission داریم برای مثال مجوز مدیریت کاربران، مجوز مدیریت محصولات و... . خب این مجوز ها ما بخوایم به یک کاربر بدیم ممکنه هست 20 تا مجوز میخوایم بدیم و این برای یک کاربر نباشه مثلا 10 تا از کارمند ها میخوان این مجوز ها داشته باشند، کلی باید زحمت کشید و..، همینطور در کد هم ما باید کلی مجوز چک کنید و این سخت هست.

بخوایم یک مثال ساده بزنم فرض کنید ما توی دستامون یک سری وسایل داریم و خب این وسایل چون زیاد هستند سخته حمل و نقل و جا به جایی آنها. برای اینکار میایم این وسایل داخل یک جعبه میزاریم و با خودمون جا به جا میکنیم این جوری خیلی راحت میتونیم مدیریتشون کنیم.

حالا داستان اینه که شما در کنار مجوز (permission) یک بخش دیگه داریم به نام مقام (role) که نقش همون جعبه انجام میده. شما یک سری مجوز دارید که به یک مقام وصلش میکنید. 

برای مثال شما فرض کنید یک بخش حسابداری دارید توی نرم افزار. کارمندان حسابداری باید مجوز دارایی، درآمد، صورت حساب و... دسترسی داشته باشند، برای اینکار شما کافیه که یک مقام بسازید و یک سری مجوز ها لازم فقط یک بار به مقام بدید. حالا زمانی که شما این مقام ها بهش میدید به راحتی میتونید به کارمندان بخش حسابداری مقام حسابداری بدید و مجوز هاشون کم و زیاد کنید.

# شروع به استفاده

ساخت یک مجوز (Permission)

برای ساخت یک مجوز و مقام کافیه از مدل های خوده پکیج استفاده کنید. شما نیاز دارید که یک نام به آنها بدید:

use SpatiePermissionModelsRole;
use SpatiePermissionModelsPermission;

$role = Role::create(['name' => 'writer']);
$permission = Permission::create(['name' => 'edit articles']);

اختصاص دادن یک مجوز به یک مقام

خب بالاتر در مورد اینکه مجوز ها به مقام ها اختصاص پیدا میکنند صحبت کردیم، برای اینکه شما یک مجوز به یک مقام اختصاص بدید کافیه از مثال زیر الگو بگیرید:

$role->givePermissionTo($permission);
$permission->assignRole($role);

شما میتونید یک مجوز به چندین مقام بدید همینطور برعکس!

اختصاص دادن چندین مجوز و مقام

شما همینطور میتونید بدون نیاز به حلقه، چندین مجوز و مقام به هم اختصاص بدید:

$role->syncPermissions($permissions);
$permission->syncRoles($roles);

حذف کردن مجوز یا مقام

شما برای حذف یک مجوز یا یک مقام میتونید از متد های زیر کمک بگیرید:

$role->revokePermissionTo($permission);
$permission->removeRole($role);

دریافت تمامی مجوز های یک کاربر

شما میتونید با متد های خفن این پکیج به راحتی مجوز های یک کاربر دریافت کنید و یک سری عملیات انجام بدید. جلوتر روش چک کردن مجوز و.. هم خواهیم گفت:

// get a list of all permissions directly assigned to the user
$permissionNames = $user->getPermissionNames(); // collection of name strings
$permissions = $user->permissions; // collection of permission objects

// get all permissions for the user, either directly, or from roles, or from both
$permissions = $user->getDirectPermissions();
$permissions = $user->getPermissionsViaRoles();
$permissions = $user->getAllPermissions();

// get the names of the user's roles
$roles = $user->getRoleNames(); // Returns a collection

Scopes

این پکیج به شما یک سری اسکوپ (scope) میده که میتونید به راحتی کاربران با مجوز و مقام خاص دریافت کنید:

$users = User::role('writer')->get(); // Returns only users with the role 'writer'
$nonEditors = User::withoutRole('editor')->get(); // Returns only users without the role 'editor'
$users = User::permission('edit articles')->get(); // Returns only users with the permission 'edit articles' (inherited or directly)
$usersWhoCannotEditArticles = User::withoutPermission('edit articles')->get(); // Returns all users without the permission 'edit articles' (inherited or directly)

اختصاص دادن یک مجوز به یک کاربر

شما نیاز دارید یک سری مجوز به کاربرانتون اختصاص بدید، برای اینکار خوده پکیج یک سری متد داره که میتونید ازش استفاده کنید:

$user->givePermissionTo('edit articles');

// You can also give multiple permission at once
$user->givePermissionTo('edit articles', 'delete articles');

// You may also pass an array
$user->givePermissionTo(['edit articles', 'delete articles']);

حذف مجوز از کاربر

شما نیاز دارید یک سری مجوز ها از کاربرانتون حذف کنید، برای این کار میتونید از متد های زیر استفاده کنید:

$user->revokePermissionTo('edit articles');

چک کردن داشتن مجوز برای یک کاربر

شما بخواید چک کنید که کاربرتون مجوز های خاصی دارند میتونید از متد های زیر استفاده کنید:

$user->can('edit articles');
$user->hasPermissionTo('edit articles');
$user->hasPermissionTo('1');
$user->hasPermissionTo(Permission::find(1)->id);
$user->hasPermissionTo($somePermission->id);

همینطور میتونید چندین مجوز چک کنید:

$user->hasAnyPermission(['edit articles', 'publish articles', 'unpublish articles']);

در روش بالا کاربر هر کدوم از مجوز ها داشته باشه مقدار true برمیگردونه اما این متد باید تمامی مجوز ها داشته باشه:

$user->hasAllPermissions(['edit articles', 'publish articles', 'unpublish articles']);

اختصاص دادن مقام به کاربر

مثل مجوز ها، مقام ها هم میتونید به کاربر اختصاص بدید برای اینکار بازم متد داریم و به راحتی این کار انجام میدیم:

$user->assignRole('writer');

// You can also assign multiple roles at once
$user->assignRole('writer', 'admin');
// or as an array
$user->assignRole(['writer', 'admin']);

حذف کردن یک مقام از کاربر

شما میتونید یک مقام از کاربر حذف کنید:

$user->removeRole('writer');

چک کردن مقام یک کاربر

شما میتونید مثل مجوز ها، مقام های یک کاربر چک کنید. توصیه من اینه همیشه از مجوز ها استفاده کنید بهتره چون مقام ها متغیر هستند و.. :

$user->hasRole('writer');

// or at least one role from an array of roles:
$user->hasRole(['editor', 'moderator']);

$user->hasAnyRole(['writer', 'reader']);
// or
$user->hasAnyRole('writer', 'reader');

$user->hasAllRoles(Role::all());

$user->hasExactRoles(Role::all());

Blade Directive

شما میتونید در فرانت یا همون blade از یک سری دایرکتیو استفاده کنید برای اینکه چک کنید کاربر چه دسترسی هایی داره:

@can('edit articles')
  //
@endcan

@role('writer')
    I am a writer!
@else
    I am not a writer...
@endrole

@hasanyrole($collectionOfRoles)
    I have one or more of these roles!
@else
    I have none of these roles...
@endhasanyrole
// or
@hasanyrole('writer|admin')
    I am either a writer or an admin or both!
@else
    I have none of these roles...
@endhasanyrole

@hasallroles($collectionOfRoles)
    I have all of these roles!
@else
    I do not have all of these roles...
@endhasallroles
// or
@hasallroles('writer|admin')
    I am both a writer and an admin!
@else
    I do not have all of these roles...
@endhasallroles

@unlessrole('does not have this role')
    I do not have the role
@else
    I do have the role
@endunlessrole

@hasexactroles('writer|admin')
    I am both a writer and an admin and nothing else!
@else
    I do not have all of these roles or have more other roles...
@endhasexactroles

Super Admin چیه؟

مفهوم سوپر ادمین به این معنی است که یک کاربر بتونه به تمامی قسمت های یک اپلیکیشن دسترسی داشته باشه و مدیر اصلی هست. شما میتونید یک مجوز یا مقام درست کنید و در Service Provider یک Gate Before تعریف کنید:

use IlluminateSupportFacadesGate;
// ...
public function boot()
{
    // Implicitly grant "Super Admin" role all permissions
    // This works in the app by using gate-related functions like auth()->user->can() and @can()
    Gate::before(function ($user, $ability) {
        return $user->hasRole('Super Admin') ? true : null;
    });
}

نظر من این هست که یک مجوز (permission) درست کنید بهتره.

ویدیو رایگان آموزش پکیج Laravel Role-Permission

مستندات پکیج


0 🔥
1 🎉
0 😮
0 👍
1 💜
0 👏
میلاد خسروی
نویسنده کد نیوز

برنامه نویس فان | Fun Developer یک آدم ساده که عاشق برنامه نویسی و کد زدنه :) تلاش میکنه تا به بقیه کمک کنه. توسعه دهنده هسته لاراول و فضای اوپن سورس. فاندر پرانتز و کد نیوز.

0+ نظر

برای ثبت نظر ابتدا ورود کنید.

0 نظر

    اولین نفر باش که نظر ثبت میکنی :) یعنی یه کامنت به ما نمیرسه 😁