使用带有apiResource路由的策略

时间:2018-05-15 07:14:20

标签: laravel

目前我正在编写Laravel 5.6 REST API。现在我想确保我的终点:

我的应用程序中的每个用户都有一个角色。基于此,用户应该能够访问某些端点,否则应该得到403错误。为此,我想使用Policies因为,当用作中间件时,他们可以在传入请求到达我的路由或控制器之前授权操作。

我声明我的端点是这样的:

Route::apiResource('me', 'UserController');

我现在的问题是,如果我想使用Policies作为中间件,我必须指定像此middleware('can:update,post')这样的(HTTP)方法。当我在路线声明中使用apiResource时,我该怎么做?

BTW:目前我为每种方法写了一个FormRequest(这很痛苦)并在那里进行授权。切换到return true中间件后,我可以在authorize方法中Policies吗?

2 个答案:

答案 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');
}