ایجاد احراز هویت ساده مبتنی بر نقش کاربری در لاراول
در این پست می خواهیم در احراز هویت دو روش سطح دسترسی برای لاراول آموزش دهیم و نیازی به استفاده پکیچ های دسترسی لاراول نیست.
ایجاد نقش های تکی (Single roles)
دستور ایجاد جدول زیر :
php artisan make:migration add_role_column_to_users_table --table=users
کد زیر:
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up()
{
Schema::table('user', function (Blueprint $table) {
$table->string('role')->nullable();
});
}
public function down()
{
Schema::table('user', function (Blueprint $table) {
$table->dropColumn('role');
});
}
}
میدولور (Middleware)
با دستور زیر فایل EnsureUserHasRole را ایجاد کنید:
php artisan make:middleware EnsureUserHasRole
کد زیر:
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
class EnsureUserHasRole
{
public function handle(Request $request, Closure $next, string $role)
{
if ($request->user()->role === $role) {
return $next($request);
}
abort(403);
}
}
نکته: هر زمان که با یک شی Request سر و کار دارید، می توانید بدون استفاده از Auth یا کمک کننده auth()->user() کاربر احراز هویت شده را دریافت کنید. فقط $request->user() را فراخوانی کنید و کاربر احراز هویت شده را برمی گرداند. شما می توانید این کار را در کنترلرها نیز انجام دهید.
ثبت در میدولور
کد زیر در مسیر فایل app/Http/Kernel.php وارد کنید:
protected $routeMiddleware = [ 'role' => \App\Http\Middleware\EnsureUserHasRole::class, // Other route middleware... ];
در مسیر روت زیر می توانید به صورت زیر دسترسی را تعریف کنید:
Route::middleware(['auth', 'role:admin'])->group(function () {
// User is authentication and has admin role
});
ایجاد نقش های متعدد (Multiple roles)
با دستور زیر جدول و مدل Role را ایجاد کنید:
php artisan make:model Role -m
کد زیر برای جدول Role :
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up()
{
Schema::create('roles', function (Blueprint $table) {
$table->id();
$table->string('name')->unique();
$table->timestamps();
});
}
public function down()
{
Schema::dropIfExists('roles');
}
}
یک جدول دیگر با نامک role_user ایجاد کنید:
php artisan make:migration create_role_user_table --create=role_user
کد زیر:
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up()
{
Schema::create('role_user', function (Blueprint $table) {
$table->primary(['role_id', 'user_id']);
$table->foreignId('role_id')->constrained()->cascadeOnDelete();
$table->foreignId('user_id')->constrained()->cascadeOnDelete();
});
}
public function down()
{
Schema::dropIfExists('role_user');
}
}
در مدل های Role و User رابطه belongsToMany تعریف کنید:
مدل Role
class Role extends Model
{
public function users()
{
return $this->belongsToMany(User::class);
}
}
مدل User
class User extends Authenticatable
{
public function roles()
{
return $this->belongsToMany(Role::class);
}
}
تعریف میدولور (Middleware)
کد زیر :
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
class EnsureUserHasRole
{
public function handle(Request $request, Closure $next, string $role)
{
if ($request->user()->roles()->where('name', '=', $role)->exists()) {
return $next($request);
}
abort(403);
}
}
در مسیر Route میدولور آن role:foo
تعریف می شود و یعنی هر عنوان برای نقش کاربری تعریف کردید که به عنوان مثال author به صورت role:author
تعریف می کنید.