目前我正在编写Laravel 5.6 REST API。现在我想确保我的终点:
我的应用程序中的每个用户都有一个角色。基于此,用户应该能够访问某些端点,否则应该得到403错误。为此,我想使用Policies
因为,当用作中间件时,他们可以在传入请求到达我的路由或控制器之前授权操作。
我声明我的端点是这样的:
Route::apiResource('me', 'UserController');
我现在的问题是,如果我想使用Policies
作为中间件,我必须指定像此middleware('can:update,post')
这样的(HTTP)方法。当我在路线声明中使用apiResource
时,我该怎么做?
BTW:目前我为每种方法写了一个FormRequest
(这很痛苦)并在那里进行授权。切换到return true
中间件后,我可以在authorize
方法中Policies
吗?
答案 0 :(得分:0)
您可以定义route groups,具有共同行为的路由(中间件,前缀等)。
以下内容应该有效:
Route::middleware('can:update,post')->group(function () {
Route::apiResource('me', 'UserController');
//more routes
});
您也可以为路线添加前缀:
Route::middleware('can:update,post')->group(function () {
Route::prefix('users')->group(function () {
Route::apiResource('me', 'UserController'); //Translated to ex: /users/me
Route::prefix('books')->group(function () {
Route::apiResource('{book}', 'UserController'); //Translated to ex: /users/me/book_1
});
});
});
P.S:之前我没有使用过资源,但它应该完成这项工作
答案 1 :(得分:0)
由于您使用FormRequest::class
来验证请求数据,因此最好的做法是首先检查用户是否有权发出请求。对于Laravel 5.6,最干净的解决方案是在资源控制器的__construct()
方法中手动指定每个策略。
public function __construct()
{
$this->middleware('can:viewAny,App\Post')->only('index');
$this->middleware('can:create,App\Post')->only('store');
$this->middleware('can:view,post')->only('show');
$this->middleware('can:update,post')->only('update');
$this->middleware('can:delete,post')->only('delete');
}
如果您要验证控制器内部的表单数据而不是使用FormRequest::class
,则更干净的解决方案是也要授权控制器内部的用户。
public function store(Request $request)
{
$this->authorize('create', Post::class);
// The user is authorized to make this request...
$request->validate([
//Validation Rules
});
// The form data has been successfully validated...
// Controller logic...
}
从Laravel 5.7开始,您可以使用控制器的__construct()
方法上的一行代码来完成所有这些操作。
public function __construct()
{
$this->authorizeResource(Post::class, 'post');
}