طراحی سطوح دسترسی در لاراول

برای دوستان سوال بود که چجوری میشه سطوح دسترسی برای لاراول ایجاد کرد . خوب برخی آموزش های ایرانی هستند که با هزینه زیاد ، هیچی یاد نمیدن. خوب این هم یک مدلشه دیگه . کسی که همه چیز رو میگه کامل بلدم و یادتون میدم ، یه جای کارش میلنگه . بگذریم ...

به نظر من نوشتن هر چیزی ، بهترین کار نیست . لاراول برای راحتی برنامه نویسا اومده (Love beautiful code? We do too.)

خوب . اول از همه باید بریم به پکیج هیجان انگیز spatie/laravel-permission . لینک زیر کاملا همه چیز رو گفته :

https://github.com/spatie/laravel-permission

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

composer require spatie/laravel-permission

به فایل config/app.php برید و داخل providers کد زیر رو قرار بدید :

'providers' => [
    // ...
    Spatie\Permission\PermissionServiceProvider::class,
];

حالا migration رو میتونیم منتشر کنیم :

$ php artisan vendor:publish --provider="Spatie\Permission\PermissionServiceProvider" --tag="migrations"
$ php artisan migrate
$ php artisan vendor:publish --provider="Spatie\Permission\PermissionServiceProvider" --tag="config"

حالا به config/permissions.php برید. داخل این فایل میتونین کاملا هر تنظیماتی که میخواید رو اعمال کنین . تا اینجای کار که چیز خاصی نبود . یک نصب کردن معمولی بود . اما داستان اونجایی شروع میشه که ما میخوایم پنل مدیریت و یا حتی بخش کاربری رو برای سطوح دسترسی مدیریت کنیم .

من یک مثال طراحی میکنم ، بعدش میریم که امکانات دسترسی رو روی اون مثال پیاده کنیم .

فرض کنیم که ما یک پنل داریم که دو بخش داره . بخش مدیریت کاربران و بخش ایجاد پست .

من میخوام که این دو بخش برای مدیر باز باشه . اما بخش مدیریت کاربران برای کاربر با سطح دسترسی manager فقط قابل رویت باشه ، برای کاربر با سطح دسترسی author کلا قابل رویت نباشه .

و اینکه کاربر با دسترسی manager بتونه پست ها رو بخونه ، اما کاربر با دسترسی author بتونه یک پست هم ارسال کنه .

پس ما دو گروه داریم .

گروه author و گروه manager .

گروه author میتونه پست ایجاد کنه و پست ها رو ببینه .

گروه manager میتونه پست ها را بخونه و کاربران را هم بخونه . ( عملیات ویرایش ندارد )

خوب . اول از همه ما یک model داریم . به اسم users که خود لاراول ایجاد کرده . مدل رو به این شکل تغییر بدید .

use Illuminate\Foundation\Auth\User as Authenticatable;
use Spatie\Permission\Traits\HasRoles;

class User extends Authenticatable
{
    use HasRoles;

    // ...
}

قسمت HasRoles رو دقت کنید .

اول از همه باید یک کنترلر بسازیم ( به هر شکل و شمایلی که دوست دارید ) که بتونه جداول permissions رو پر کنه تا از روی اونا تصمیم گیری انجام بشه .

یک کنترلر بسازید و کلاس های مربوط رو بالا use کنید و با متودهایی که داریم ، گروه های کاربری رو بسازیم .

use Spatie\Permission\Models\Role;
use Spatie\Permission\Models\Permission;
.......
$authorRole=Role::create(['name' => 'author']);
$authorPerms=Permission::create(['name' => 'edit posts','name' => 'view posts']);
$managerRole=Role::create(['name' => 'manager']);
$managerPerms=Permission::create(['name' => 'view users','name' => 'manager view posts']);  
//Assignee roles to perms
$authorRole->givePermissionTo($authorPerms);
$managerRole->givePermissionTo($managerPerms);
.......

خوب از کدا معلومه داریم چی کار میکنیم . حالا بریم داخل blade . دوتا منو داریم که یکی ما رو میبره به صفحه کاربران و یکی هم میبره به صفحه پست ها .

<a href="{{route('users')}}> All users </a>
<a href="{{route('posts')}}> All posts </a>

سناریو رو حالا پیاده میکنیم .

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

@role('manager')
<a href="{{route('users')}}> All users </a> 
@endrole
@hasanyrole('manager|author')
<a href="{{route('posts')}}> All posts </a>
@endhasanyrole

داخل این قسمت گفتیم اگر role برابر بود با manager بتونه کاربران رو ببینه ( لینک مربوط به کاربران رو ) و اگر کاربر یکی از سطوح manager و یا author بود هم بتونه لینک پست ها رو ببینه .

دقت کنید که اینجا ما روی متود های کنترلر posts و یا users شرط نزاشتیم . کاربر اگر به صورت مستقیم و دستی داخل آدرس بار ، آدرس مورد نظر رو بنویسه میتونه وارد اون لینک خاص بشه . پس باید متود های مربوط به این آدرس ها رو هم ببندیم . برای این هم spatie تابع های خوبی داره .

public function index(){
$user=Auth::user();
if($user->hasRole('manager'){
      //return view for users list 
}
else{
//show user 403 permission denied 
}
}

این متود برای manager بود . همین کار رو میتونین برای پست ها و حتی هر دکمه و هر عملیات دیگه هم انجام بدید .

من چون قصدم آموزش دادن نیست و فقط در حد راهنمایی ( در حد سوادم ) میخواستم بنویسم ، در همین حد بسنده میکنم و توصیه میکنم که داکیومنت spatie/permissions رو کامل مطالعه کنین . نحوه نوشتن رو گفتم . باز اگر سوالی بود ، کامنت کنین در خدمتم .