【问题标题】:Laravel Policies - How to Pass Multiple Arguments to functionLaravel 策略 - 如何传递多个参数来运行
【发布时间】:2016-07-28 17:19:27
【问题描述】:

我正在尝试授权用户角色删除/更新帖子。我正在使用策略来执行此操作,但我只能将一个参数传递给策略函数。如果我传递的不仅仅是用户和另一个变量,则该变量不会传递到函数中。

模型:用户有很多角色,一个角色可以发布多个帖子。因此,出于授权目的,我必须将帖子的 character_id 与当前角色的 id 进行比较...-

根据docs,您可以将更多倍数传递给 Gate Facade:

Gate::define('delete-comment', function ($user, $post, $comment) {
    //
});

但我无论如何都找不到政策。我要做的是注入 Request 对象以获取授权所需的对象。基本上我什至不需要用户对象。

public function update(User $user, Post $post)
{
    return $user->id === $post->user_id;
}

使用 Request 对象是可行的,但感觉很 hacky。有没有更好的方法来实现这一点?

编辑:

CharacterLocationController 中,我有一个方法show,我想在显示资源之前授权该操作。

public function show(Request $request, Character $character, Location $location)
{
    $this->authorize([$location, $character]);
    ...
}

该策略是这样注册的:'App\Location' => 'App\Policies\LocationPolicy'AuthServiceProvider

我转储了传递给策略函数的数组,它只输出$location

public function show(User $user, $data) {
    dd($data); // expecting location and character
    return !$location->private || $location->authorized->contains($this->character);
}

【问题讨论】:

    标签: php laravel authorization laravel-5.2


    【解决方案1】:

    我认为这里可能对哪些函数在做什么有一些混淆。

    当你使用

    Gate::define('delete-comment', function ($user, $post, $comment) {
        //
    });
    

    或者在CommentPolicy

    public function delete(User $user, Post $post, Comment $comment)
    {
        return $user->id === $post->user_id;
    }
    

    您所做的只是定义规则。在这一点上,我们并不担心传递任何东西,只担心我们收到的对象可以或应该能够相互交互。这两者之间的唯一区别是在使用策略时,它只是一种将所有规则抽象为一个简单易读的类的简单方法。如果您的应用程序可能包含数百个表和模型,那么如果这些规则散布在您的应用程序中,那么它会很快变得混乱,因此策略将有助于使它们保持井井有条。

    当您实际检查某人是否有权做某事时,您应该传递这些物品。例如,当您执行以下操作时,

    if (Gate::allows('delete-comment', [$post, $comment])) {
        // 
    }
    

    或者如果在CommentController

    $this->authorize('delete', [$post, $comment]);
    

    这就是控制哪些参数将被传递给策略或Gate::define 方法。根据文档,$user 参数已经为您添加了,所以在这种情况下,您只需要担心传递正确的 $post$comment 被修改。

    【讨论】:

    • 感谢您的澄清,尽管我还有一个问题。 Policy 本身附加到一个类(如 eloquent 模型),因此在传递适当类型的对象作为第二个参数时,会自动调用该规则。如果您传递一个数组,就像您在 CommentController 示例中所做的那样,那么使用什么策略?它是否试图解析传递数组中的第一个对象?
    • 困扰我的不是在数组中传递多个额外的参数。 Laravel 文档在这方面可能会更详细一些。但是很高兴发现问题。
    • 当方法不需要模型实例(例如 create)时,请注意将类名添加到数组中,例如$this->authorize('create', [Comment::class, $post]);
    • @piscator 我可以对authorizeResource()做同样的事情吗?
    • @piscator 的注释实际上在很多情况下处理策略(和存储模型)时非常有用和需要。 OP 也许您可以将其添加到您的答案中?还是谢谢你们俩
    猜你喜欢
    • 2021-12-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-30
    • 2011-11-18
    • 2019-12-28
    • 2017-06-01
    • 1970-01-01
    相关资源
    最近更新 更多