Laravel Authorization là cơ chế xác định người dùng có được phép thực hiện một hành động cụ thể hay không. Thông qua Gate, Policy và Middleware, Laravel cung cấp nhiều cách kiểm soát quyền truy cập rõ ràng và linh hoạt. Bài viết dưới đây giúp bạn hiểu cách hoạt động và triển khai Laravel Authorization trong ứng dụng thực tế.
Laravel Authorization là gì?
Laravel Authorization là cơ chế phân quyền trong Laravel, dùng để xác định người dùng có được phép thực hiện một hành động hay truy cập một tài nguyên nào đó hay không.
Ví dụ:
- Người dùng thông thường được xem bài viết nhưng không được xóa.
- Nhân viên có thể cập nhật đơn hàng nhưng không được quản lý tài khoản.
- Admin có quyền chỉnh sửa và xóa người dùng.
- Chỉ chủ sở hữu bài viết mới được phép chỉnh sửa bài viết đó.
Authorization khác với Authentication:
| Cơ chế | Mục đích |
| Authentication | Xác định người dùng là ai |
| Authorization | Xác định người dùng được phép làm gì |
Có thể hiểu đơn giản: Authentication kiểm tra danh tính, Authorization kiểm tra quyền hạn.
Nếu đang tìm hiểu tổng thể về Laravel, bạn có thể tham khảo Học Laravel để tiếp cận các kiến thức từ nền tảng đến triển khai ứng dụng thực tế.
Laravel Authorization hoạt động như thế nào?
Một luồng Authorization cơ bản thường diễn ra như sau:
Người dùng đăng nhập → Laravel xác định User → kiểm tra quyền → cho phép hoặc từ chối hành động.
Ví dụ người dùng truy cập URL:
/posts/15/edit
Laravel có thể kiểm tra:
- Người dùng đã đăng nhập chưa?
- Người dùng có quyền sửa bài viết không?
- Bài viết có thuộc về người dùng đó không?
- Nếu hợp lệ thì cho phép chỉnh sửa.
- Nếu không có quyền thì trả về lỗi hoặc từ chối truy cập.
Laravel hỗ trợ nhiều cơ chế Authorization, trong đó phổ biến nhất là Gate và Policy.
Laravel Gate dùng để làm gì?
Gate phù hợp với những quy tắc phân quyền đơn giản, thường không gắn quá chặt với một Model cụ thể.
Gate thường được định nghĩa trong:
app/Providers/AppServiceProvider.php
Ví dụ kiểm tra quyền xóa bài viết:
use App\Models\User;
use Illuminate\Support\Facades\Gate;
Gate::define(‘delete-post’, function (User $user) {
return $user->is_admin;
});
Sau đó kiểm tra quyền:
if (Gate::allows(‘delete-post’)) {
// Cho phép xóa
}
Hoặc:
if (Gate::denies(‘delete-post’)) {
abort(403);
}
Khi nào nên sử dụng Gate?
Gate phù hợp khi logic tương đối đơn giản, chẳng hạn:
- Kiểm tra người dùng có phải Admin không.
- Cho phép truy cập một khu vực nhất định.
- Kiểm tra quyền thực hiện một hành động đơn giản.
- Kiểm tra một tính năng theo vai trò người dùng.
Nếu logic phân quyền liên quan trực tiếp đến một Model như Post, Order hoặc User thì Policy thường phù hợp hơn.
Laravel Policy là gì?
Policy là lớp chứa các logic Authorization liên quan đến một Model hoặc Resource cụ thể.
Ví dụ ứng dụng có Model:
Post
Bạn có thể tạo Policy:
php artisan make:policy PostPolicy –model=Post
Policy có thể chứa các phương thức như:
public function update(User $user, Post $post)
{
return $user->id === $post->user_id;
}
Logic trên cho phép người dùng chỉnh sửa bài viết nếu họ chính là người tạo bài viết.
Trong Controller:
public function update(Request $request, Post $post)
{
$this->authorize(‘update’, $post);
// Cập nhật bài viết
}
Nếu người dùng không có quyền, Laravel sẽ từ chối yêu cầu.
Vì sao Policy hữu ích?
Policy giúp đưa logic phân quyền ra khỏi Controller, từ đó:
- Code dễ đọc hơn.
- Logic Authorization được tập trung.
- Dễ tái sử dụng.
- Dễ kiểm thử.
- Phù hợp với ứng dụng có nhiều Model và quy tắc phân quyền.
Phân quyền bằng Middleware
Middleware có thể được sử dụng để kiểm tra quyền trước khi request đi đến Controller.
Ví dụ:
Route::middleware(‘auth’)->group(function () {
Route::get(‘/dashboard’, [DashboardController::class, ‘index’]);
});
Middleware auth kiểm tra người dùng đã đăng nhập hay chưa.
Với các yêu cầu phức tạp hơn, bạn có thể xây dựng Middleware riêng để kiểm tra role hoặc permission.
Ví dụ:
class AdminMiddleware
{
public function handle($request, Closure $next)
{
if (!auth()->user()?->is_admin) {
abort(403);
}
return $next($request);
}
}
Sau đó áp dụng Middleware cho route quản trị.
Middleware đặc biệt hữu ích khi cần bảo vệ toàn bộ nhóm route thay vì kiểm tra từng hành động trong Controller.
Phân quyền theo Role và Permission
Trong các hệ thống lớn, Authorization thường không chỉ dừng ở việc kiểm tra Admin hay User.
Có thể xây dựng hệ thống gồm:
- Role: Vai trò của người dùng.
- Permission: Quyền cụ thể.
- User: Người dùng được gán một hoặc nhiều vai trò.
Ví dụ:
| Role | Permission |
| Admin | Xem, thêm, sửa, xóa |
| Editor | Xem, thêm, sửa |
| Author | Xem, thêm |
| User | Xem |
Khi đó thay vì kiểm tra:
$user->is_admin
ứng dụng có thể kiểm tra:
$user->can(‘update-post’)
Cách này phù hợp với hệ thống có nhiều nhóm người dùng và quyền hạn khác nhau.
Nếu bạn đang học các kiến thức nền tảng như Routing, Middleware, Controller, Eloquent hay Authentication, danh mục Laravel cơ bản là nguồn phù hợp để xây dựng kiến thức theo từng chủ đề.
Kiểm tra quyền trong Blade
Authorization không chỉ được kiểm tra ở Controller. Bạn cũng có thể kiểm tra quyền ngay trong Blade.
Ví dụ:
@can(‘update’, $post)
<a href=”{{ route(‘posts.edit’, $post) }}”>
Chỉnh sửa
</a>
@endcan
Nếu người dùng không có quyền update, nút chỉnh sửa sẽ không được hiển thị.
Tuy nhiên, việc ẩn nút trên giao diện không thay thế cho kiểm tra Authorization ở phía server.
Người dùng vẫn có thể tự nhập URL hoặc gửi HTTP request trực tiếp. Vì vậy Controller, Policy hoặc Middleware vẫn phải kiểm tra quyền.
Authorization trong API Laravel
Đối với Laravel API, Authorization cũng đóng vai trò quan trọng.
Ví dụ API cập nhật bài viết:
public function update(Request $request, Post $post)
{
$this->authorize(‘update’, $post);
$post->update($request->validated());
return response()->json($post);
}
Nếu không có quyền, request sẽ bị từ chối thay vì cho phép người dùng sửa dữ liệu trái phép.
Đây là nguyên tắc quan trọng khi xây dựng REST API: không được chỉ dựa vào giao diện frontend để kiểm soát quyền truy cập.
Gate và Policy khác nhau như thế nào?
| Tiêu chí | Gate | Policy |
| Phạm vi | Logic quyền tổng quát | Logic gắn với Model |
| Cấu trúc | Đơn giản | Có tổ chức hơn |
| Phù hợp | Quyền đơn giản | CRUD và Resource |
| Ví dụ | Kiểm tra Admin | User sửa Post |
| Dự án lớn | Có thể dùng | Thường phù hợp hơn |
Có thể áp dụng cả hai trong cùng một dự án.
Gate phù hợp với những quyền mang tính tổng quát, còn Policy phù hợp khi quyền gắn với một Model cụ thể.
Những lỗi thường gặp khi triển khai Authorization
Chỉ kiểm tra quyền ở giao diện
Ẩn nút Delete không có nghĩa người dùng không thể gọi API Delete.
Luôn kiểm tra quyền ở phía server.
Nhầm Authentication với Authorization
Người dùng đăng nhập thành công không đồng nghĩa họ có quyền thực hiện mọi hành động.
Authentication → Người này là ai?
Authorization → Người này được làm gì?
Đưa quá nhiều logic vào Controller
Nếu Controller chứa hàng loạt điều kiện:
if ($user->role === ‘admin’) …
if ($user->id === $post->user_id) …
if ($user->can_edit) …
code sẽ nhanh chóng khó quản lý.
Với các quy tắc phức tạp, nên cân nhắc sử dụng Policy hoặc cơ chế phân quyền riêng.
Không kiểm tra quyền trên tài nguyên cụ thể
Ví dụ:
return $user->is_editor;
có thể chưa đủ.
Nếu yêu cầu là “chỉ được sửa bài viết do chính mình tạo”, cần kiểm tra cả User và Post:
return $user->id === $post->user_id;
Khi nào nên dùng Gate, Policy và Middleware?
Có thể lựa chọn theo nguyên tắc đơn giản:
- Gate: Quyền đơn giản, không phụ thuộc nhiều vào Model.
- Policy: Quyền liên quan trực tiếp đến Model hoặc Resource.
- Middleware: Kiểm soát quyền truy cập ở cấp Route hoặc nhóm Route.
- Role/Permission: Hệ thống có nhiều vai trò và quyền chi tiết.
Trong một ứng dụng thực tế, các cơ chế này hoàn toàn có thể kết hợp với nhau.
Kết luận
Laravel Authorization là thành phần quan trọng giúp kiểm soát người dùng được phép thực hiện những hành động nào trong ứng dụng. Laravel cung cấp nhiều lựa chọn như Gate, Policy và Middleware, từ đó đáp ứng cả hệ thống đơn giản lẫn ứng dụng có cấu trúc phân quyền phức tạp.
Nếu mới làm quen với Laravel, nên bắt đầu từ Authentication, Middleware và Gate trước. Khi ứng dụng có nhiều Model và quy tắc quyền hạn, Policy kết hợp Role/Permission sẽ giúp hệ thống dễ tổ chức và mở rộng hơn.
