Laravel政策:如何使“代表”行为成为可能

问题描述 投票:0回答:1

这可能是有关Laravel内部工作的问题。

我正在编写一个应用程序。只有登录的用户才能创建特定类型的记录,这很容易,您只需将$this->middleware('auth')添加到控制器中就可以了。

现在我想要更复杂的东西,具有admin角色的用户可以代表某些用户创建/编辑这种记录。想象一下诸如StackOverflow之类的东西,用户可以编辑另一个用户提出的问题,但是可以创建。就是这样,管理员可以代表user()创建帖子:

所以我的create()中有我的PronController,就像这样:

function create($sid, $uid=NULL) {
    // $sid is section id, where the post is going to be created... don't mind...

    // if $uid (user id) is null, it will take the user from Auth::user()->id
    $user = empty($uid) ? Auth::user() : User::findOrFail($uid);

    // I want that only "admin" can use this $uid parameter, so I plan to use
    // a Policy:
    $this->authorize('create', $user);        
}

PronPolicy中的策略非常简单:

function create(User $authUser, User $user) {
    return ($authUser->id === $user->id) || $authUser->isAdmin;
}

现在,我认为这应该可以,但是不能。它永远不会达到此edit()(我放置了Log's)

所以我所做的就是将$this->authorize()行更改为:

$this->authorize('createpron', $user);

并将UserPolicy()(UserPolicy !!!)更改为:

function createpron(User $authUser, User $user) {
    return ($authUser->id === $user->id) || $authUser->isAdmin;
}

现在这可以按我的意愿工作。但是我不知道为什么。看起来Laravel在参数中搜索对象类型,然后为该参数激活策略,对吗?

我不知道,尽管我的代码正在运行,但在我看来,这有点脏,因为创建“ Pron”应该是Pron的策略,而不是用户的策略。我在概念上做错了吗?什么是实现此目标的正确方法?

php laravel
1个回答
0
投票

看起来像Laravel在参数中搜索对象类型,然后激活该参数的策略,对吗?

正确! The docs mention this

策略是组织授权逻辑围绕特定模型或资源的类。例如,如果您的应用程序是博客,则您可能具有Post模型和相应的PostPolicy来授权用户操作,例如创建或更新帖子。

通过将$user参数传递给$this->authorize(),您正在询问当前用户是否可以对该特定记录执行操作。

您在做什么不是conceptually错误(正在运行),它只是将几个不同的授权混合在一起,因此感觉有些混乱或不清楚。这是我要改善的方法:

首先分离授权。您确实发生了两个单独但相关的权限检查:

  1. 当前User可以代表另一个User起作用吗?
  2. 最终用户(当前或代表)可以创建Pron吗?

#1可以被设置为登机口或策略,这取决于您是否想部分代表通过User的传递。例如,如果您只能代表您自己组织内的用户采取行动,那将很有用。 UserPolicy将是一个不错的选择。

#2的实现就好像您没有任何代理功能。所以也许只是return true,因为任何人都可以创建它们,或者您的应用需要创建Pron的能力。

然后,分别制定它们。

function create($sid, $uid = null)
{
    $user = Auth::user();

    if (!empty($uid)) {
        $user = User::findOrFail($uid);

        $this->authorize('on-behalf-of', $user);
    }

    $this->authorizeForUser($user, 'create', new Pron());

    // Continue your create logic...
}

这提供了一些好处:

  • Controller会更明确地读取正在发生的授权动作及其相关性
  • 闸门和策略不必过多依赖混合记录类型,并且可以严格比较对不带参数的指定用户的权限
  • 对权限进行更严格的控制(例如,如果用户X无法创建帖子,则用户Y代表他们的行为仍然无法创建帖子)

可能的缺点:

  • 与上面更严格的控制相反:如果您want组合权限检查以修改它们,则不能完全解决问题。例如,用户X无法创建帖子,但是如果管理员代表他们行事,那么他们可以,以上内容无法完全解决该问题
© www.soinside.com 2019 - 2024. All rights reserved.