对一个策略使用多个Auth Guard [英] Use multiple Auth guards for one Policy
问题描述
我在Laravel 5.4项目中实现了多个Auth Guard(其中一个用于管理员,另一个用于普通用户).到目前为止,该方法已经成功运行,管理员和用户都可以登录.我现在正在尝试实现一个对两个Auth Guard都适用的Policy类.这是因为我有一些模型,希望所有管理员都可以编辑,而只有拥有该模型的用户才可以编辑.所以我已经用这种方法定义了一个策略.
I have implemented multiple Auth guards in a Laravel 5.4 project (one of for admins and the other for regular users). This has worked successfully so far and both admins and users are able to log in. I am now trying to implement a Policy class that works for both Auth guards. This is because I have certain models that I want all administrators to edit and only users who own the model to be able to edit. So I have defined a policy with this method.
App \ Policies \ ModelPolicy
public function update(User $user, Model $model)
{
if ($user->id === $model->user_id) {
return true;
}
if (Auth::guard('admin')->check()) {
return true;
}
return false;
}
然后使用我的模型使用的任何控制器方法:
Then in whatever controller method I have for my model:
App \ Http \ Controllers \ ModelController
public function update(Model $model)
{
$this->authorize('update', $model);
// update model
}
如果普通用户已登录,这将非常有效.但是,当管理员用户登录时,它甚至都无法达到该策略(我从错误日志记录中知道这一点).我猜想,如果 Auth :: check()
中的默认防护失败,Policy类会执行某些操作来自动拒绝请求.但是,由于对我的用户来说,拥有多个保护措施之一(不仅仅是默认保护措施)是有效的,因此,我需要绕过此行为.
This works perfectly if a regular user is logged in. However, when an admin user is logged in, it doesn't even reach the policy (I know this from error logging). I am guessing that the Policy class does something to automatically deny a request if the default guard in Auth::check()
fails. However, since it is valid for my users to have one of several guards (not just the default), I need to bypass this behavior.
我知道我可以在我的控制器方法中实现管理逻辑,并且只有在我知道我正在与非管理员打交道时才使用该策略:
I know I could implement the admin logic in my controller method and only use the policy if I know I am dealing with a non-admin:
public function update(Model $model)
{
if (!Auth::guard('admin')->check()) {
$this->authorize('update', $model);
}
// update model
}
但是,如果我的管理员条件比简单地登录更复杂,那么这很快就会失控.更重要的是,所有这些逻辑都属于策略,而不是弄乱我的控制器.
However, this can quickly spiral out of control if my admin condition is more complicated than simply being logged in. More importantly, all of this logic belongs in a Policy, not muddying up my controller.
如何将相同的Policy类用于多个身份验证防护?
How is it possible to use the same Policy class for multiple authentication guards?
推荐答案
我最终覆盖了基本控制器类上的 authorize
方法,使正确的 Guard 成为默认的 Guard.然后,传递到我的策略中的 $ user
参数将成为当前用户登录身份验证的实例.
I ended up overriding the authorize
method on the base controller class to make the correct Guard the default Guard. Then, the $user
argument passed into my policy will be an instance of whichever Auth guard the current user is logged in as.
app/Http/Controllers/Controller.php
use Auth
class Controller extends BaseController
{
use DispatchesJobs, ValidatesRequests;
use AuthorizesRequests {
authorize as protected baseAuthorize;
}
public function authorize($ability, $arguments = [])
{
if (Auth::guard('admin')->check()) {
Auth::shouldUse('admin');
}
$this->baseAuthorize($ability, $arguments);
}
}
现在,该策略将通过 我的用户模型或管理模型传递,我需要确保删除参数的类型提示并检查该模型的类型传入.我不需要执行任何 Auth :: check()
,因为我知道传入的 $ user
必须是的登录用户.我想要的类型.
Now that the Policy will be passed in either my User model or my Admin model, I need to make sure that I remove the type-hinting for the argument and check the type of the model that is passed in. I don't need to do any Auth::check()
because I know that the $user
that is passed in must be a logged in user of the type that I want.
App \ Policies \ ModelPolicy
use App\User;
public function update($user, Model $model)
{
if ($user instanceof User) {
return $user->id == $userId;
}
// Is an Admin
return true;
}
现在我可以使用所需的Auth Guard来执行我的策略中想要执行的任何操作.
And now I have access to desired Auth guard to do whatever I want with it in my Policy.
这篇关于对一个策略使用多个Auth Guard的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!