Zend framework2 zfcuser-白名单路由和所有子路由

Zend framework2 zfcuser-白名单路由和所有子路由,zend-framework2,zfcuser,Zend Framework2,Zfcuser,我在应用程序中使用ZfcUser模块来保护对/admin路由的访问。因为我想阻止/admin的所有子路由,除了/login、/register等 为了做到这一点,我在这里添加了一个来自accepted answer的代码- 它可以工作,但是它也会阻止对根路由的访问——因为有很多根路由,我真的不想将每个路由都添加到白名单中。是否有任何方法仅限制对/admin路由的访问 是否有任何方法仅限制对/admin路由的访问 这实际上意味着,与白名单相比,您需要黑名单或更改条件检查的逻辑 根据您的要求,您可以

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

为了做到这一点,我在这里添加了一个来自accepted answer的代码-

它可以工作,但是它也会阻止对根路由的访问——因为有很多根路由,我真的不想将每个路由都添加到白名单中。是否有任何方法仅限制对/admin路由的访问

是否有任何方法仅限制对/admin路由的访问

这实际上意味着,与白名单相比,您需要黑名单或更改条件检查的逻辑

根据您的要求,您可以只检查部分路线,类似这样的情况

$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;
    }
}
是否有任何方法仅限制对/admin路由的访问

这实际上意味着,与白名单相比,您需要黑名单或更改条件检查的逻辑

根据您的要求,您可以只检查部分路线,类似这样的情况

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

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

列出要限制访问的控制器。因此,与控制器相关的一切都应该受到限制。只要你需要限制访问,就在这里列出它们。您不再需要使用
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);
}    

让我们知道它是否对您有帮助

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

列出要限制访问的控制器。因此,与控制器相关的一切都应该受到限制。只要你需要限制访问,就在这里列出它们。您不再需要使用
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);
}    

让我们知道它是否对您有帮助

我建议看看ZfcRbac。我想这正是你想要的:

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

这会将以
admin
开头的任何路由限制为
admin
角色的用户。由于默认操作模式是基于黑名单的(“保护模式”是“允许”),因此您只需为要限制访问的路由指定规则。任何与RouteGuard不匹配的路由都可以公开访问

我建议看看ZfcRbac。我想这正是你想要的:

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

这会将以
admin
开头的任何路由限制为
admin
角色的用户。由于默认操作模式是基于黑名单的(“保护模式”是“允许”),因此您只需为要限制访问的路由指定规则。任何与RouteGuard不匹配的路由都可以公开访问

在这种情况下,黑名单和白名单都不是很好的解决方案,因为我仍然被迫键入每个子路由。在更改strpos中变量的位置($currentRoute,$route)后,您的解决方案似乎可以正常工作,但在我测试时,这有点奇怪。我将更新这个主题,因为我将在明天进一步调查它。谢谢大家!@榕树叫声;是的,它应该是
strpos($currentRoute,$route)
。我已经更新了我的答案。经过一些测试,它工作正常,但是需要以某种方式指定每一条路线是相当烦人的。控制器解决方案解决了这个问题。谢谢你的帮助,我很感激!在这种情况下,黑名单和白名单都不是很好的解决方案,因为我仍然被迫键入每个子路由。在更改strpos中变量的位置($currentRoute,$route)后,您的解决方案似乎可以正常工作,但在我测试时,这有点奇怪。我将更新这个主题,因为我将在明天进一步调查它。谢谢大家!@榕树叫声;是的,它应该是
strpos($currentRoute,$route)
。我已经更新了我的答案。经过一些测试,它工作正常,但是需要以某种方式指定每一条路线是相当烦人的。控制器解决方案解决了这个问题。谢谢你的帮助,我很感激!是的,到目前为止,这个解决方案可以完成任务!谢谢你的明确解释,你再次救了我:-)是的,这个解决方案到目前为止都能解决问题!谢谢你的解释,你又救了我一次:-)