Cách phân quyền Laravel với Middleware và Spatie Permission

Trong các ứng dụng web thực tế, việc quản lý tài khoản người dùng không chỉ dừng lại ở đăng nhập hay đăng ký, mà còn bài toán cốt lõi: Ai được phép làm gì? Mặc dù Laravel cung cấp sẵn tính năng Gate và Policy rất mạnh mẽ, nhưng khi dự án lớn lên với hàng chục vai trò (Role) và hàng trăm quyền hạn (Permission) khác nhau, việc tự quản lý sẽ trở nên cồng kềnh. Lúc này, package Spatie Laravel Permission kết hợp cùng Middleware chính là cứu cánh hoàn hảo. Bài viết này sẽ hướng dẫn bạn cách thiết lập hệ thống phân quyền Laravel một cách bài bản nhất.

1. Spatie Permission và Middleware là gì?

  • Spatie Laravel Permission: Đây là package mã nguồn mở phổ biến hàng đầu trong hệ sinh thái Laravel giúp quản lý Roles (Vai trò) và Permissions (Quyền hạn) thông qua cơ sở dữ liệu một cách trực quan, mạch lạc.
  • Middleware trong phân quyền: Đóng vai trò như một “chốt kiểm soát” (guard) nằm giữa request của người dùng và Controller. Khi kết hợp với Spatie, Middleware giúp chặn ngay từ đầu các truy cập trái phép vào các route cụ thể trước khi logic code kịp thực thi.
READ  Cách validate form trong Laravel chuẩn chỉnh, bắt lỗi chi tiết

Nếu bạn mới bắt đầu tiếp cận các khái niệm xử lý request hay định tuyến cơ bản, hãy dành chút thời gian ôn tập lại nền tảng tại chuyên mục thủ thuật trước khi bắt tay vào triển khai các mô hình phân quyền nâng cao này.

2. Cài đặt và cấu hình Spatie Permission trong Project

Bước 1: Cài đặt qua Composer

Mở terminal tại thư mục gốc của project Laravel và chạy câu lệnh sau để tải package:

Bash

composer require spatie/laravel-permission

Bước 2: Xuất bản Migration và Config

Sau khi cài đặt xong, bạn cần publish file cấu hình và các bảng migration cơ sở dữ liệu bằng lệnh Artisan:

Bash

php artisan vendor:publish –provider=”Spatie\Permission\PermissionServiceProvider”

Lệnh này sẽ sinh ra các file migration cấu trúc bảng cho roles, permissions, model_has_roles, v.v. Tiếp theo, chạy lệnh migrate để đẩy các bảng này lên MySQL:

Bash

php artisan migrate

3. Thiết lập Model User

Để Model User của bạn có thể sử dụng các tính năng gán vai trò và quyền hạn, hãy thêm trait HasRoles vào file app/Models/User.php:

PHP

namespace App\Models;

use Illuminate\Foundation\Auth\User as Authenticatable;

use Spatie\Permission\Traits\HasRoles; // <– Import trait

class User extends Authenticatable

{

    use HasRoles; // <– Khai báo sử dụng

    protected $fillable = [

        ‘name’,

        ’email’,

        ‘password’,

    ];

}

4. Sử dụng Middleware để phân quyền cho Route

Spatie cung cấp sẵn các middleware tiện ích để bạn bảo vệ route trực tiếp trong file routes/web.php hoặc routes/api.php.

Các middleware chính được hỗ trợ:

  • role: Kiểm tra người dùng có sở hữu vai trò cụ thể hay không.
  • permission: Kiểm tra người dùng có quyền hạn cụ thể hay không.
  • role_or_permission: Kiểm tra người dùng có vai trò HOẶC quyền hạn được chỉ định.
READ  Cách upload file trong Laravel lưu trữ an toàn, đúng chuẩn

Ví dụ áp dụng thực tế:

PHP

use Illuminate\Support\Facades\Route;

// Chỉ tài khoản có vai trò ‘admin’ mới truy cập được trang quản trị

Route::get(‘/admin/dashboard’, [AdminController::class, ‘index’])

    ->middleware([‘auth’, ‘role:admin’]);

// Tài khoản phải có quyền ‘edit-posts’ mới được vào route này

Route::get(‘/posts/edit’, [PostController::class, ‘edit’])

    ->middleware([‘auth’, ‘permission:edit-posts’]);

// Hoặc kết hợp nhiều điều kiện

Route::get(‘/reports’, [ReportController::class, ‘index’])

    ->middleware([‘auth’, ‘role:admin|editor’]);

Lưu ý: Nếu muốn tùy chỉnh tên alias của các middleware này, bạn có thể cấu hình thêm trong file bootstrap/app.php (đối với Laravel 11) hoặc app/Http/Kernel.php (đối với các phiên bản cũ hơn).

5. Kiểm tra quyền hạn trực tiếp trong Controller hoặc Blade

Bên cạnh việc chặn ở Route Middleware, đôi khi bạn cần ẩn/hiện nút bấm trên giao diện hoặc kiểm tra logic ngầm bên trong Controller.

Kiểm tra trong Blade Template:

Spatie cung cấp cácBlade directive cực kỳ trực quan để render giao diện theo quyền:

HTML

@role(‘admin’)

    <a href=”{{ route(‘admin.users.index’) }}”>Quản lý thành viên hệ thống</a>

@endrole

@can(‘edit-posts’)

    <button class=”btn btn-warning”>Chỉnh sửa bài viết</button>

@endcan

Kiểm tra trong Controller:

Bạn có thể sử dụng phương thức hasRole() hoặc can() trực tiếp trên đối tượng $request->user() hoặc Auth::user():

PHP

public function destroy(Request $request, $id)

{

    if (! $request->user()->hasRole(‘admin’)) {

        abort(403, ‘Bạn không có quyền thực hiện hành động này.’);

    }

    // Logic xóa dữ liệu tại đây…

}

Tổng kết

Việc kết hợp giữa MiddlewareSpatie Permission giúp hệ thống phân quyền trong Laravel trở nên vô cùng gọn gàng, linh hoạt và dễ mở rộng khi dự án phình to. Để trang bị thêm cho mình một nền tảng kiến thức vững chắc, đáp ứng các tiêu chuẩn bảo mật và tối ưu hóa mã nguồn tốt nhất, bạn có thể ghé thăm website Học Laravel để khám phá thêm nhiều chuỗi bài viết chuyên sâu khác.

READ  Xử Lý Errors Và Lỗi Logging Trong Laravel

 

Để lại một bình luận

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *