2016-02-10 92 views
8

案例:我正在使用Laravel的Authorization作为使用策略的骨干构建论坛。我运行的支票的例子有:@can('view', $forum),@can('reply', $topic),Gate::allows('create_topic', $forum)等。这些检查基本上检查用户角色是否具有特定论坛,主题或帖子的权限。这样我可以为我的应用程序中的每个论坛赋予角色非常特定的权限。访客用户的授权和策略

的问题是,所有这些检查的经过大门类,具体的方法称为raw()这在其第一行做到这一点:

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

这与论坛的问题时提出的问题。如果用户没有登录,Laravels Gate类会自动返回false。

我需要能够触发我的策略即使没有用户。说我的[email protected]方法,我做if(User::guest() && $forum->hasGuestViewAccess()) { return true }

但正如你所看到的,这种方法永远不会触发。

有没有办法让我仍然使用Laravel的授权功能与来宾用户?

回答

2

我不知道的超级自然的方式来做到这一点,但如果有必要,你可以改变门的用户解析器,这是负责寻找用户(默认情况下它从Auth::user()读取)。

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

这将是由你来回报什么样的客人对象(只要它是truthy),但我可能会使用类似空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)的调用中。

+0

你也可以通过使用'Gate :: forUser($ guestUser)'解决解决问题的方法,但这对你的情况来说似乎没有用处,因为你仍然需要为来宾和用户使用不同的代码。 – tdhsmith

1

我刚刚发布了package,它允许将权限逻辑应用到访客用户。它稍微修改Laravel的授权,以在未解析用户时返回Guest对象而不是null。由于没有经过认证的用户,因此每个授权检查现在都会将其授权给Gate,而不是立即授权。