这可能是有关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的策略,而不是用户的策略。我在概念上做错了吗?什么是实现此目标的正确方法?
看起来像Laravel在参数中搜索对象类型,然后激活该参数的策略,对吗?
策略是组织授权逻辑围绕特定模型或资源的类。例如,如果您的应用程序是博客,则您可能具有
Post
模型和相应的PostPolicy
来授权用户操作,例如创建或更新帖子。
通过将$user
参数传递给$this->authorize()
,您正在询问当前用户是否可以对该特定记录执行操作。
您在做什么不是conceptually错误(正在运行),它只是将几个不同的授权混合在一起,因此感觉有些混乱或不清楚。这是我要改善的方法:
首先分离授权。您确实发生了两个单独但相关的权限检查:
User
可以代表另一个User
起作用吗?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...
}
这提供了一些好处:
可能的缺点: