Laravel 策略 - 如何将多个参数传递给函数

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/36482737/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-14 13:33:39  来源:igfitidea点击:

Laravel Policies - How to Pass Multiple Arguments to function

phplaravelauthorizationlaravel-5.2

提问by Johannes

I'm trying to authorize a users character to delete/update post. I was using policies to do so, but I could only pass one parameter to the policy function. If I pass more than the user and another variable, the variable isn't passed into the function.

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

Models: User has many characters, a character can post multiple posts. So for authorization purposes, I would have to compare the post's character_id with the current character's id...-

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

Per the docs, you can pass more multiples to the Gate Facade:

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

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

But I couldn't find anyway to do so with policies. What I had to do was to inject the Request object to get the object needed for authorization. Basically I wouldn't even need the User Object.

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

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

Using the Request object works, but it feels very hacky. Is there a nicer way to achieve this?

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

edit:

编辑:

In the CharacterLocationControllerI have a method showand I want to authorize the action before showing the resource.

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

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

The policy is registered like this: 'App\Location' => 'App\Policies\LocationPolicy'in the AuthServiceProvider

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

I dumped the array passed to the policy function, and it only outputs the $location.

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

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

回答by user1669496

I think there is possibly some confusion here on what functions are doing what.

我认为这里可能对哪些功能在做什么有些困惑。

When you use

当你使用

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

Or in the CommentPolicy

或者在 CommentPolicy

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

All you are doing is defining the rules. At this point, we aren't worried about passing anything, only that the objects we received can or should be able to interact with each other. The only difference between these two is when using policies, it's just an easy way to abstract all your rules into one simple and easy to read class. If you have an app with potentially hundreds of tables and models, it will get confusing fast if you have these rules littered all over your app so policies would help to keep them all organized.

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

It's when you are actually checking if someone has permission to do something when you should be passing these items along. For example, when you do the following,

当你真正检查某人是否有权做某事时,你应该传递这些项目。例如,当您执行以下操作时,

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

Or if in the CommentController

或者如果在 CommentController

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

That is what controls which parameters are going to be passed to the policy or the Gate::definemethod. According to the docs, the $userparameter is already added for you so in this case, you only need to worry about passing the correct $postand $commentbeing modified.

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