访客用户的授权和策略

Pis*_*hio 8 php laravel laravel-5 laravel-5.1

案例:我正在建立一个论坛,使用Laravel的授权作为使用策略的主干.我运行检查的例子是这样的东西@can('view', $forum),并且@can('reply', $topic),Gate::allows('create_topic', $forum)等等.这些检查主要检查,如果用户角色对特定的论坛,主题或帖子的许可.这样我就可以为我的应用程序中的每个论坛赋予角色非常具体的权限.

问题是所有这些检查都通过Gate类,特别是raw()在第一行中调用的方法:

if (! $user = $this->resolveUser()) {
    return false;
}
Run Code Online (Sandbox Code Playgroud)

这在处理论坛时会出现问题.我的应用程序的访客也应该被允许查看我的论坛,但是从上面的代码可以看出,如果用户没有登录,Laravels Gate类会自动返回false.

即使没有用户,我也需要能够触发我的策略.用我的ForumPolicy@view方法说,我做if(User::guest() && $forum->hasGuestViewAccess()) { return true }

但正如您所看到的,此方法永远不会触发.

我还有办法让访客用户使用Laravel的授权功能吗?

小智 2

我不知道有什么超自然的方法来实现这一点,但如果有必要,您可以更改门的用户解析器,它负责查找用户(默认情况下它从读取Auth::user())。

由于解析器受到保护并且没有设置器,因此您需要在创建时对其进行修改。该门在 Laravel 中实例化AuthServiceProvider。您可以扩展此类,并将配置中对它的引用替换app.providers为您的子类。

返回什么样的来宾对象取决于您(只要它是真实的),但我可能会使用类似空User模型的东西:

protected function registerAccessGate()
{
    $this->app->singleton(GateContract::class, function ($app) {
        return new Gate($app, function () use ($app) {
            $user = $app['auth']->user();
            if ($user) {
                return $user;
            }
            return new \App\User;
        });
    });
}
Run Code Online (Sandbox Code Playgroud)

您可以更进一步,在其上设置一个特殊属性,例如$user->isGuest,甚至定义一个特殊的来宾类或常量。

或者,您可以在该Auth级别调整流程,以便所有注销的会话都包含在对 的调用中Auth::setUser($guestUserObject)。