Laravel Gates
Tổng quan về Gates:
- Gates là simply closures, xác định xem người dùng có quyền hay không với một hành động cụ thể.
- Gates được sử dụng cả ở template blade, routes, controller. Gates sẽ không gắn với model cụ thể nào, gate sẽ sử dụng các thông tin truyền vào với tham số đầu tiên là user.
- Gates được viết (định nghĩa) ở App\Providers\AuthServiceProvider.
1. Khởi tạo Gates:
- Khởi tạo Gates trong App\Providers\AuthServiceProvider:
<?php namespace App\Providers;
use App\Models\User;
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
use Illuminate\Support\Facades\Gate;
class AuthServiceProvider extends ServiceProvider
{
/**
* The policy mappings for the application.
*
* @var array
*/
protected $policies = [
'App\Models\Model' => 'App\Policies\ModelPolicy',
];
/**
* Register any authentication / authorization services.
*
* @return void
*/
public function boot()
{
$this->registerPolicies();
$this->setGates();
}
private function setGates()
{
Gate::define('update-post', function (User $user, Post $post) {
return $user->id === $post->user_id;
});
}
}
- Định nghĩa một gate là
update-post
mục đính xác định xem user có quyền update bài viết hay không. - Tham số đầu tiên truyền vào được mặc định là
user
đang đăng nhập, tiếp theo truyền vào các tham số ở đây là bài viết muốn cập nhật. - Hàm trả về giá trị true hoặc fales nếu true thì
user
có quyền update bài viết và ngược lại.
2. Sử dụng Gates.
Trong controller:
- Sử dung Method
allows
xác định xem Gate có cho phép hành động diễn ra hay không:
if (Gate::allows('update-post', $post)){
// Update the post...
}
- Sử dụng Method
denies
để từ chối hành động diễn ra:
if (Gate::denies('update-post', $post)) {
// The user can't update the post...
}
- Sử dụng Method
forUser
để kiểm tra quyền củauser
khácuser
đang đăng nhập:
if (Gate::forUser($user)->allows('update-post', $post)) {
// The user can update the post...
}
- Sử dụng Method
any
vànone
để sử dụng nhiều Gate kiểm tra một hành động xem có được phép diễn ra hay không:
if (Gate::any(['update-post', 'delete-post'], $post)) {
// The user can update or delete the post...
}
if (Gate::none(['update-post', 'delete-post'], $post)) {
// The user can't update or delete the post...
}
- Ngoài ra còn một số method khác
check
,authorize
,inspect
,can
,cannot
.
Trong Middleware:
Route::post('/update-post', [App\Http\Controllers\PostController::class, 'update'])->can('update-post');
- Trong ví dụ trên kiểm tra user có quyền
update-post
trước khi tới rquest tới controller.
Trong Blade Templates:
@can('update-post', $post)
<!-- The current user can update the post... -->
@endcan
- Ở đây màn hình chỉ hiển thị các bài viết mà
user
đang đăng nhập có quyền cập nhật.
3. Kết luận.
- Chúng ta đã tìm hiểu thêm một công cụ giúp giải quyết bài toán phân quyền trong Laravel ngoài Middleware và Policy.
- Gates thường được sử dụng ở tầng
Controller
, giúp kiểm soát quyền của cácuser
trong hệ thống một cách dễ dàng (logic phần quyền được viết tập chung ởAuthServiceProvider
).
Tài liệu tham khảo:
https://laravel.com/docs/8.x/authorization#gates
https://www.php.net/manual/en/class.closure.php