zfcuser - 白名单路由和所有childroutes

时间:2017-07-05 07:49:47

标签: zend-framework2 zfcuser

我在我的应用程序中使用ZfcUser模块来保护对/ admin路由的访问。因为我想阻止/ admin的所有childroutes,除了/ login,/ register等。

为了做到这一点,我在这里添加了一个接受答案的代码 - 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);
  }

它可以工作,但是它也阻止了对根路由的访问 - 并且因为它们很多,我真的不想将每一条路由添加到白名单。有没有办法限制只访问/ admin路由?

3 个答案:

答案 0 :(得分:1)

  

有没有办法限制只能访问/ admin路由?

这实际上意味着您需要 black 列表而不是 white 列表,或者更改条件检查的逻辑。

根据您的要求,您可以检查路线的一部分,如下所示。

$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;
    }
}

答案 1 :(得分:1)

您可以通过检查每个控制器名称而不是检查路由名称来保护对 admin 区域的访问。因此,您可以更轻松地控制用户的可访问性,并且比检查路由名称更便携。

列出要限制访问的控制器。所以与控制器相关的一切都应该受到限制。无论您需要限制访问权限,只需在此处列出即可。您不再需要使用onBootstrap()方法弄脏手。

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

$whitelist中输入正确的控制器名称。您可以通过在$controller方法中回显onBootstrap()来获得该结果。请查看下面的注释区域。

接下来查找控制器名称,然后检查列表中是否列出了该名称。

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);
}    

告诉我们它是否对您有帮助!

答案 2 :(得分:1)

我建议看看ZfcRbac。它有一个"guards" functionality,我认为这正是您正在寻找的:

$user_id = $_SESSION['myid'];
$sql = "SELECT user_friends.accid,users_student.studentuniqueid FROM user_friends INNER JOIN IN (user_friends.user1,user_friends.user2)=users_student.studentuniqueid WHERE user1 = '$user_id' OR user2 = '$user_id' ORDER BY users_student.name ASC ";

这会将以return [ 'zfc_rbac' => [ 'guards' => [ 'ZfcRbac\Guard\RouteGuard' => [ 'admin*' => ['admin'] ] ] ] ]; 开头的所有路由限制为admin角色的用户。由于默认操作模式是基于黑名单的("保护模式"是"允许"),因此您只需要为要限制访问的路由指定规则。任何与RouteGuard不匹配的路线都可以公开访问。