2017-07-05 107 views
0

我在我的應用中使用ZfcUser模塊來保護對/ admin路由的訪問。當我想阻止/管理所有childroutes,除/登錄,/註冊等zfcuser - 白名單路由和所有的孩子郵件路由

爲了做到這一點,我已經添加了從這裏接受的答案代碼 - Zend Framework 2 - Global check for authentication with ZFCUser

protected $whitelist = array('zfcuser/login', 'default'); 

    public function onBootstrap($e) 
    { 
     $app = $e->getApplication(); 
     $em = $app->getEventManager(); 
     $sm = $app->getServiceManager(); 

     $list = $this->whitelist; 
     $auth = $sm->get('zfcuser_auth_service'); 

     $em->attach(MvcEvent::EVENT_ROUTE, function($e) use ($list, $auth) { 
      $match = $e->getRouteMatch(); 

      // No route match, this is a 404 
      if (!$match instanceof RouteMatch) { 
       return; 
      } 

      // Route is whitelisted 
      $name = $match->getMatchedRouteName(); 
      if (in_array($name, $list)) { 
       return; 
      } 

      // User is authenticated 
      if ($auth->hasIdentity()) { 
       return; 
      } 

      // Redirect to the user login page, as an example 
      $router = $e->getRouter(); 
      $url  = $router->assemble(array(), array(
       'name' => 'zfcuser/login' 
     )); 

      $response = $e->getResponse(); 
      $response->getHeaders()->addHeaderLine('Location', $url); 
      $response->setStatusCode(302); 

      return $response; 
     }, -100); 
    } 

它但是它也阻止了對根路由的訪問 - 而且還有很多這樣的路由,我並不想將每一條路由都添加到白名單中。有沒有辦法限制只訪問/管理路線?

回答

1

您可以通過檢查每個控制器名稱,而不是檢查路線名稱保護訪問管理區域。因此,您可以更輕鬆地控制用戶的可訪問性,並且比檢查路由名稱更具可移植性。

列出您想要限制訪問的控制器。所以與控制器相關的一切都應該受到限制。無論您需要限制訪問權限,只需在此列出。您不需要用onBootstrap()方法讓自己的手變得髒兮兮的。

protected $whitelist = array(
    'ZfcUser\Controller\User', // or use 'zfcuser' 
); 

$whitelist擺正控制器名稱。您可以通過在onBootstrap()方法中回顯$controller來實現。請查看下面的註釋區域。

下一步趕上控制器名稱,然後檢查是否列出您的列表中。

public function onBootstrap(MvcEvent $e) 
{ 
    $app = $e->getApplication(); 
    $em = $app->getEventManager(); 
    $sm = $app->getServiceManager(); 

    $list = $this->whitelist; 
    $auth = $sm->get('zfcuser_auth_service'); 

    $em->attach(MvcEvent::EVENT_ROUTE, function($e) use ($list, $auth) { 

     // get the current route 
     $route = $e->getRouteMatch()->getMatchedRouteName(); 

     // check for 'zfcuser/login' and 'zfcuser/register' routes 
     if (in_array($route, array('zfcuser/login', 'zfcuser/register'))) { 
      return; 
     } 

     // get the current controller name 
     $controller = $e->getRouteMatch()->getParam('controller'); 

     // Check the right controller name by echoing 
     // echo $controller;   

     // check if a user has access on the current controller 
     if (in_array($controller, $list)) { 

      if(! $auth->hasIdentity()) { 

       $router = $e->getRouter(); 
       $url = $router->assemble(array(), array(
        'name' => 'zfcuser/login' 
       )); 

       $response = $e->getResponse(); 
       $response->getHeaders()->addHeaderLine('Location', $url); 
       $response->setStatusCode(302); 

       return $response; 
      } 
     } 

    }, -100); 
}  

讓我們知道它是否對您有幫助!

+0

是的,這個解決方案到目前爲止做的工作!謝謝你的明確解釋,你再次拯救我:-) – ficus

+0

你永遠是歡迎的! :) – unclexo

1

有什麼方法可以限制只訪問/管理路線?

這將真正意味着而非白名單你需要一個黑色列表或更改條件檢查的邏輯。

根據您的要求,您可以檢查路線的一部分,就像這樣。

$this->whitelist = [ 
    'zfcuser/login', 
    'default' 
]; 

// Route is whitelisted 
$currentRoute = $match->getMatchedRouteName(); 

foreach($this->whitelist as $route) { 
    if (0 === strpos($currentRoute, $route)) { 
     // we matched the start of the route, 
     // e.g every route under 'default' would match this 
     return; 
    } 
} 
+0

在這種情況下,黑名單和白名單都不是好的解決方案,因爲我仍然被迫輸入每一個孩子的路線。 您的解決方案似乎在改變strpos($ currentRoute,$ route)中的變量位置後正在工作,但是當我測試它時有些奇怪。我會更新這個話題,因爲我會在明天進行更深入的調查。 謝謝! – ficus

+0

@ficus哎呀;是的它應該是'strpos($ currentRoute,$ route)'。我已經更新了我的答案。 – AlexP

+0

經過一些測試後,它可以正常工作,但是需要以某種方式指定每條單一路線是非常煩人的。控制器解決方案解決了這個問題謝謝你的幫助,我明白了! – ficus

0

我建議看看ZfcRbac。它有一個"guards" functionality,我認爲是你在尋找什麼:

return [ 
    'zfc_rbac' => [ 
     'guards' => [ 
      'ZfcRbac\Guard\RouteGuard' => [ 
       'admin*' => ['admin'] 
      ] 
     ] 
    ] 
]; 

這將限制與adminadmin角色開始用戶的任何途徑。由於默認操作模式是基於黑名單的(「保護模式」爲「允許」),因此您只需要爲要限制訪問的路由指定規則。任何不符合RouteGuard的路線均可公開訪問。