Laravel策略-如何传递多个参数以发挥作用 [英] Laravel Policies - How to Pass Multiple Arguments to function

查看:527
本文介绍了Laravel策略-如何传递多个参数以发挥作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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.

模型:用户有多个角色,一个角色可以发布多个帖子.因此,出于授权目的,我将不得不比较帖子的character_id与当前角色的ID ...-

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...-

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

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

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

但是我却找不到政策来做到这一点.我要做的是注入Request对象以获得授权所需的对象.基本上,我什至不需要用户对象.

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.

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

使用Request对象是可行的,但是感觉很hacky.有没有更好的方法可以做到这一点?

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

CharacterLocationController中,我有一个方法show,我想在显示资源之前对操作进行授权.

In the CharacterLocationController I have a method show and I want to authorize the action before showing the resource.

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

该策略的注册方式如下:'App\Location' => 'App\Policies\LocationPolicy'AuthServiceProvider

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

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

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

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

推荐答案

我认为这里的功能可能在做什么方面有些混乱.

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

使用时

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

或在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])) {
    // 
}

或者在CommentController

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

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

That is what controls which parameters are going to be passed to the policy or the Gate::define method. According to the docs, the $user parameter is already added for you so in this case, you only need to worry about passing the correct $post and $comment being modified.

这篇关于Laravel策略-如何传递多个参数以发挥作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆