简体   繁体   English

来宾用户的授权和政策

[英]Authorization and Policies for Guest users

Case: I'm building a forum using Laravel's Authorization as a backbone using policies. 案例:我正在建立一个使用Laravel授权作为策略基础的论坛。 Examples of checks I run are stuff like @can('view', $forum) , and @can('reply', $topic) , Gate::allows('create_topic', $forum) etc. These checks basically checks if the users role has that permission for the specific forum, topic or post. 我运行的检查示例包括@can('view', $forum)@can('reply', $topic)Gate::allows('create_topic', $forum)等。这些检查基本上检查是否用户角色具有对特定论坛,主题或帖子的权限。 That way I can give roles very specific permissions for each forum in my application. 这样,我可以为应用程序中的每个论坛赋予角色非常特定的权限。

The issue is that all of these checks go through the Gate class, specifically a method called raw() which in its first line does this: 问题在于所有这些检查都要经过Gate类,特别是称为raw()的方法,该方法在其第一行中执行此操作:

if (! $user = $this->resolveUser()) {
    return false;
}

This presents an issue when dealing with forums. 这在与论坛打交道时会出现问题。 Guests to my application should also be allowed to view my forum, however as you can see from the code above, Laravels Gate class automatically returns false if the user is not logged in. 还应允许我的应用程序的访客访问我的论坛,但是,从上面的代码中可以看到,如果用户未登录,Laravels Gate类将自动返回false。

I need to be able to trigger my policies even if there is no user. 即使没有用户,我也必须能够触发我的策略。 Say in my ForumPolicy@view method, I do if(User::guest() && $forum->hasGuestViewAccess()) { return true } 在我的ForumPolicy@view方法中说,我执行if(User::guest() && $forum->hasGuestViewAccess()) { return true }

But as you can see, this method will never trigger. 但是如您所见,此方法永远不会触发。

Is there a way for me to still use Laravel's authorization feature with guest users? 有没有办法让我仍然对来宾用户使用Laravel的授权功能?

I'm not aware of a super natural way to accomplish this, but if it's necessary, you could change the gate's user resolver , which is responsible for finding users (by default it reads from Auth::user() ). 我不知道一种超自然的方法来完成此操作,但是如果有必要,您可以更改gate的用户解析器 ,该解析器负责查找用户(默认情况下,它从Auth::user()读取)。

Since the resolver is protected and has no setters, you'll need to modify it on creation. 由于解析器受保护且没有设置器,因此您需要在创建时对其进行修改。 The gate is instantiated in Laravel's AuthServiceProvider . 在Laravel的AuthServiceProvider实例化 You can extend this class and replace the reference to it in the app.providers config with your subclass. 您可以扩展此类,并用子类替换app.providers配置中对app.providers的引用。

It's going to be up to you what kind of guest object to return (as long as it's truthy), but I'd probably use something like an empty User model: 这取决于您要返回哪种访客对象(只要是真实的),但是我可能会使用诸如空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;
        });
    });
}

You could go a step further and set a special property on it like $user->isGuest , or even define a special guest class or constant. 您可以更进一步,并在其上设置特殊属性,例如$user->isGuest ,甚至可以定义特殊的来宾类或常量。

Alternatively you could adjust your process at the Auth level so that all logged-out sessions are wrapped in a call to Auth::setUser($guestUserObject) . 或者,您可以在Auth级别调整流程,以便将所有注销的会话包装在对Auth::setUser($guestUserObject)的调用中。

I just released a package that allows permission logic to be applied to guest users. 我刚刚发布了一个软件包 ,该软件包允许将权限逻辑应用于来宾用户。 It slightly modifies Laravel's Authorization to return a Guest object instead of null when no user is resolved. 当没有用户解析时,它会稍微修改Laravel的Authorization以返回Guest对象而不是null Also every authorization check now makes it to the Gate instead of failing authorization instantly because there isn't an authenticated user. 现在,每一次授权检查都将发送到Gate,而不是因为没有经过身份验证的用户而立即使授权失败。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM