使用单一策略方法覆盖对资源的所有操作

时间:2018-10-11 17:21:31

标签: laravel authorization

我有一个名为Post的资源。每个Post都与一个User相关,而一个User可能有多个(或零个)Posts

我正在使用Route::resource将针对Post资源的每个可能动作的路由映射到单个资源控制器PostController

现在,我希望为Post资源实施一项政策。为了使所有内容尽可能简单和简单,我希望制定以下政策:

  • 每个用户都有权执行不需要现有Post的任何操作(例如,创建)。
  • User仅被授予访问Posts的每个操作(例如,编辑,更新,删除)访问自己的Post的权限。

我现在想做的是创建一个名为access的单一策略方法,该方法将检查Post是否由User拥有。然后,在我的PostController中,每个参数中带有Post对象的方法(例如edit(Post $post))都将以

开始

$this->authorize('access', $post);

但是,我不喜欢我需要手动放置这些行。如果我忘记了其中一个,那我马上就会有一个安全漏洞。

另一方面,我有一个authorizeResource方法,该方法使授权自动进行,但要求策略具有多个方法,因此它们被映射到控制器的每个方法。另外,我尝试使用Authorize/can middleware,但没有用(也许是因为我在Route::resource映射上使用了它。)

问题是:实现我所描述的结果(即授权使用完全相同的规则访问资源的所有可能操作)的最干净,更安全的方法是什么?

1 个答案:

答案 0 :(得分:2)

您可以使用authorizeResource()并在控制器中覆盖resourceAbilityMap()方法。后一种方法返回从控制器方法到将要调用的策略方法的映射。

https://github.com/laravel/framework/blob/5.7/src/Illuminate/Foundation/Auth/Access/AuthorizesRequests.php#L105

例如

class MyController extends Controller
{
    // ...

    /**
     * Get the map of resource methods to ability names.
     *
     * @return array
     */
    protected function resourceAbilityMap()
    {
        return [
            'edit' => 'access',
            'update' => 'access',
            'destroy' => 'access',
        ];
    }

    // ...
}