访客用户的授权和政策

时间:2016-02-10 14:29:55

标签: 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;
}

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

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

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

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

2 个答案:

答案 0 :(得分:2)

我不知道实现这一目标的超自然方式,但如果有必要,您可以更改登机口的用户解析器,这是负责任的用于查找用户(默认情况下,它从Auth::user()读取)。

由于解析器受到保护并且没有设置器,因此您需要在创建时对其进行修改。大门is instantiated in Laravel's AuthServiceProvider。您可以扩展此类,并使用您的子类替换app.providers config中对它的引用。

它将取决于您返回什么样的客户对象(只要它真实的),但我可能会使用像空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;
        });
    });
}

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

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

答案 1 :(得分:1)

我刚刚发布了package,允许将权限逻辑应用于访客用户。它稍微修改了Laravel的授权,以便在没有用户解析时返回Guest对象而不是null。此外,现在每个授权检查都会进入Gate,而不是立即失败授权,因为没有经过身份验证的用户。