对一个策略使用多个Auth警卫

And*_*ker 5 laravel laravel-5

我在Laravel 5.4项目中实现了多个Auth警卫(一个用于管理员,另一个用于普通用户).到目前为止,这已经成功运行,管理员和用户都可以登录.我现在正在尝试实现一个适用于两个Auth警卫的Policy类.这是因为我有一些模型,我希望所有管理员都可以编辑,只有拥有该模型的用户才能进行编辑.所以我用这种方法定义了一个策略.

软件\政策\ 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;
}
Run Code Online (Sandbox Code Playgroud)

然后在我的模型控制器方法中:

应用程序\ HTTP \控制器\ ModelController

public function update(Model $model)
{
    $this->authorize('update', $model);

    // update model
}
Run Code Online (Sandbox Code Playgroud)

如果常规用户登录,这将完美地工作.但是,当管理员用户登录时,它甚至没有达到策略(我从错误记录中知道这一点).我猜测如果默认防护Auth::check()失败,Policy类会自动拒绝请求.但是,由于我的用户有几个警卫(不仅仅是默认值)之一是有效的,我需要绕过这种行为.

我知道我可以在我的控制器方法中实现管理逻辑,只有在我知道我正在处理非管理员时才使用该策略:

public function update(Model $model)
{
    if (!Auth::guard('admin')->check()) {
        $this->authorize('update', $model);
    }

    // update model
}
Run Code Online (Sandbox Code Playgroud)

但是,如果我的管理条件比单纯登录更复杂,这可能会迅速失控.更重要的是,所有这些逻辑都属于策略,而不是混淆我的控制器.

如何为多个身份验证保护使用相同的Policy类?

And*_*ker 6

我最终重写了authorize基本控制器类上的方法,使正确的 Guard 成为默认 Guard。然后,$user传递到我的策略中的参数将是当前用户登录的任何 Auth 防护的实例。

应用程序/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);
    }
}
Run Code Online (Sandbox Code Playgroud)

现在策略将在我的用户模型或管理模型中传递我需要确保删除参数的类型提示并检查传入模型的类型。我不需要执行任何操作Auth::check(),因为我知道$user传入的必须是我想要的类型的登录用户。

应用程序\策略\模型策略

use App\User;

public function update($user, Model $model)
{
    if ($user instanceof User) {
        return $user->id == $userId;
    }

    // Is an Admin
    return true;
}
Run Code Online (Sandbox Code Playgroud)

现在我可以访问所需的身份验证防护,以在我的策略中使用它执行我想要的任何操作。