Để phân quyền CRUD cho các trang (pages) trong Laravel sử dụng package spatie/laravel-permission
✅ Bước 1: Cài đặt package
bashCopyEditcomposer require spatie/laravel-permission
Đăng service provider và publish file config/migrations:
php artisan vendor:publish --provider="Spatie\Permission\PermissionServiceProvider"
php artisan migrate
✅ Bước 2: Cấu hình model User
Thêm HasRoles
vào model User:
phpCopyEdituse Spatie\Permission\Traits\HasRoles;
class User extends Authenticatable
{
use HasRoles;
}
✅ Bước 3: Tạo Roles và Permissions
Bạn có thể chạy trong seeder, controller hoặc tinker:
Tạo Seeder
php artisan make:seeder RolePermissionSeeder
✍ Nội dung database/seeders/RolePermissionSeeder.php
:
<?php
namespace Database\Seeders;
use Illuminate\Database\Seeder;
use Spatie\Permission\Models\Role;
use Spatie\Permission\Models\Permission;
class RolePermissionSeeder extends Seeder
{
public function run(): void
{
// Danh sách quyền CRUD cho page
$permissions = [
'view page',
'create page',
'edit page',
'delete page',
];
// Tạo quyền nếu chưa tồn tại
foreach ($permissions as $permission) {
Permission::firstOrCreate(['name' => $permission]);
}
// Tạo role admin và gán toàn bộ quyền
$admin = Role::firstOrCreate(['name' => 'admin']);
$admin->syncPermissions(Permission::all());
// Tạo role editor chỉ được xem và chỉnh sửa
$editor = Role::firstOrCreate(['name' => 'editor']);
$editor->syncPermissions(['view page', 'edit page']);
// Gán role admin cho user đầu tiên
$user = \App\Models\User::first();
if ($user) {
$user->assignRole('admin');
}
}
}
✅ Chạy Seeder:
php artisan db:seed --class=RolePermissionSeeder
✅ 2. Policy cho Page
📄 Tạo Policy
php artisan make:policy PagePolicy --model=Page
app\Policies\PagePolicy.php
<?php
namespace App\Policies;
use App\Models\Page;
use App\Models\User;
use Illuminate\Auth\Access\Response;
class PagePolicy
{
/**
* Determine whether the user can view any models.
*/
public function viewAny(User $user): bool
{
return false;
}
/**
* Determine whether the user can view the model.
*/
public function view(User $user, Page $page): bool
{
return $user->can('view page');
}
/**
* Determine whether the user can create models.
*/
public function create(User $user): bool
{
return $user->can('create page');
}
/**
* Determine whether the user can update the model.
*/
public function update(User $user, Page $page): bool
{
return $user->can('edit page');
}
/**
* Determine whether the user can delete the model.
*/
public function delete(User $user, Page $page): bool
{
return $user->can('delete page');
}
/**
* Determine whether the user can restore the model.
*/
public function restore(User $user, Page $page): bool
{
return false;
}
/**
* Determine whether the user can permanently delete the model.
*/
public function forceDelete(User $user, Page $page): bool
{
return false;
}
}
✅ 3. Đăng ký Policy trong AuthServiceProvider
AuthServiceProvider
app\Providers\AppServiceProvider.php
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use App\Models\Page;
use App\Policies\PagePolicy;
class AppServiceProvider extends ServiceProvider
{
protected $policies = [
Page::class => PagePolicy::class,
];
/**
* Register any application services.
*/
public function register(): void
{
//
}
/**
* Bootstrap any application services.
*/
public function boot(): void
{
//
}
}
✅ 4. Sử dụng Policy trong Controller hoặc Blade
Trong Controller:
$this->authorize('update', $page);
Trong Blade:
@can('create page')
<a href="{{ route('pages.create') }}">Tạo trang</a>
@endcan
@can('edit page')
<a href="{{ route('pages.edit', $page) }}">Chỉnh sửa</a>
@endcan
✅ Bước 4: Middleware kiểm tra quyền
Bạn có thể dùng middleware permission
do Spatie cung cấp.
Đăng ký middleware trong app/Http/Kernel.php
nếu chưa có:
'permission' => \Spatie\Permission\Middlewares\PermissionMiddleware::class,
'role' => \Spatie\Permission\Middlewares\RoleMiddleware::class,
Trong Laravel 11 và các phiên bản mới hơn, các middleware, bao gồm cả middleware của Spatie, sẽ được đăng ký trong file bootstrap/app.php
.
bootstrap\app.php
<?php
use Illuminate\Foundation\Application;
use Illuminate\Foundation\Configuration\Exceptions;
use Illuminate\Foundation\Configuration\Middleware;
use Spatie\Permission\Middleware\PermissionMiddleware;
use Spatie\Permission\Middleware\RoleMiddleware;
return Application::configure(basePath: dirname(__DIR__))
->withRouting(
web: __DIR__ . '/../routes/web.php',
commands: __DIR__ . '/../routes/console.php',
health: '/up',
)
->withMiddleware(function (Middleware $middleware) {
// Đăng ký middleware của Spatie tại đây
$middleware->alias([
'permission' => PermissionMiddleware::class,
'role' => RoleMiddleware::class,
]);
// Bạn cũng có thể thêm các middleware vào nhóm web hoặc api nếu cần
// $middleware->web(append: [
// \App\Http\Middleware\TrustProxies::class,
// ]);
// $middleware->api(prepend: [
// \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
// ]);
})
->withExceptions(function (Exceptions $exceptions) {
//
})->create();
Sau khi bạn đã đăng ký như trên, bạn có thể sử dụng các middleware này trong các route của mình như bình thường:
// routes/web.php
use Illuminate\Support\Facades\Route;
Route::get('/admin/posts', function () {
// Chỉ những người dùng có quyền 'manage posts' mới có thể truy cập
})->middleware(['permission:manage posts']);
Route::get('/admin/users', function () {
// Chỉ những người dùng có vai trò 'admin' mới có thể truy cập
})->middleware(['role:admin']);
Áp dụng trong route:
Route::group(['middleware' => ['auth']], function () {
Route::get('/pages', [PageController::class, 'index'])->middleware('permission:view page');
Route::get('/pages/create', [PageController::class, 'create'])->middleware('permission:create page');
Route::post('/pages', [PageController::class, 'store'])->middleware('permission:create page');
Route::get('/pages/{page}/edit', [PageController::class, 'edit'])->middleware('permission:edit page');
Route::put('/pages/{page}', [PageController::class, 'update'])->middleware('permission:edit page');
Route::delete('/pages/{page}', [PageController::class, 'destroy'])->middleware('permission:delete page');
});
✅ Bước 5: Hiển thị UI theo quyền (optional)
Trong Blade:
@can('create page')
<a href="{{ route('pages.create') }}">Tạo mới trang</a>
@endcan
Last updated
Was this helpful?