2016-02-10 114 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,而不是立即授權。