Zend framework2 Zend导航与RBAC

Zend framework2 Zend导航与RBAC,zend-framework2,zend-navigation,rbac,zend-acl,zend-layout,Zend Framework2,Zend Navigation,Rbac,Zend Acl,Zend Layout,我正在开发一个基于ZF2的网站。我有一个主导航,无论访问者/用户状态如何,它都保持不变。需要添加另一个组件/nav,这将取决于用户的状态和角色。对于访客,项目将 登记册 登录 EN(实际上是一个下拉列表,使用其他可用语言) 对于已登录的普通用户,它将显示 侧面图 注销 EN(如上所述的语言选择器) 对于某些具有特定角色/权限的用户,将有其他项目 我想使用RBAC,因为ACL看起来过于臃肿,而且只是为了检查当前登录的用户/角色是否有其他项目,我需要加载完整的ACL(我们有大约15个以上不同

我正在开发一个基于ZF2的网站。我有一个主导航,无论访问者/用户状态如何,它都保持不变。需要添加另一个组件/nav,这将取决于用户的状态和角色。对于访客,项目将

  • 登记册
  • 登录
  • EN(实际上是一个下拉列表,使用其他可用语言)
对于已登录的普通用户,它将显示

  • 侧面图
  • 注销
  • EN(如上所述的语言选择器)
对于某些具有特定角色/权限的用户,将有其他项目

我想使用RBAC,因为ACL看起来过于臃肿,而且只是为了检查当前登录的用户/角色是否有其他项目,我需要加载完整的ACL(我们有大约15个以上不同类型的角色)

我花了一些时间思考我是如何做到这一点的,下面是我的一些想法

  • 我创建了一个空的导航容器,并创建了一个工厂。在工厂中,我访问身份验证和RBAC,并根据用户的状态/角色添加页面
  • 我用所有可能的页面创建了一个完全加载的导航,然后在工厂中,在身份验证和RBAC的帮助下,我隐藏了我不想显示的页面
  • rd选项是使用视图帮助器,它将通过ServiceLayer获得RBAC并生成导航。(如和中所述。
  • 或者我可以在module.php中创建一个控制器插件或只是一个方法,并监听MVC_Render或MVC_Dispatch事件,生成所需的导航并将输出添加到视图变量
  • PS:我需要使用一个分部,因为我需要向语言选择部分添加一些CSS类。导航也将显示在布局中。

    我正在使用,我正在按照以下方式进行操作,您可以根据用户角色和导航项权限显示导航,如下所示:

    public function onBootstrap(MvcEvent $e)
    {
        $eventManager        = $e->getApplication()->getEventManager();
        $eventManager->getSharedManager()->attach(
            'Zend\View\Helper\Navigation\AbstractHelper', 
            'isAllowed', 
            array('\Application\Listener\RbacListener', 'accept')
        );
        $moduleRouteListener = new ModuleRouteListener();
        $moduleRouteListener->attach($eventManager);
    }
    
    public function accept(Event $event) { 
        $event->stopPropagation();
    
        $accepted = true;
    
        $serviceLocator = $event->getTarget()->getServiceLocator()->getServiceLocator();
        $rbac           = $serviceLocator->get('ZfcRbac\Service\Rbac');
    
        $params = $event->getParams();
        $page = $params['page'];
    
        $permission = $page->getPermission();
    
        if ($permission) {
            $accepted = $rbac->isGranted($permission);
        }
    
        return $accepted;
    }
    
    首先按如下方式向导航项目添加权限:

    public function onBootstrap(MvcEvent $e)
    {
        $eventManager        = $e->getApplication()->getEventManager();
        $eventManager->getSharedManager()->attach(
            'Zend\View\Helper\Navigation\AbstractHelper', 
            'isAllowed', 
            array('\Application\Listener\RbacListener', 'accept')
        );
        $moduleRouteListener = new ModuleRouteListener();
        $moduleRouteListener->attach($eventManager);
    }
    
    public function accept(Event $event) { 
        $event->stopPropagation();
    
        $accepted = true;
    
        $serviceLocator = $event->getTarget()->getServiceLocator()->getServiceLocator();
        $rbac           = $serviceLocator->get('ZfcRbac\Service\Rbac');
    
        $params = $event->getParams();
        $page = $params['page'];
    
        $permission = $page->getPermission();
    
        if ($permission) {
            $accepted = $rbac->isGranted($permission);
        }
    
        return $accepted;
    }
    
    “权限”=>“编辑配置文件”,

    然后在
    onBootstrap
    中附加一个侦听器,如下所示:

    public function onBootstrap(MvcEvent $e)
    {
        $eventManager        = $e->getApplication()->getEventManager();
        $eventManager->getSharedManager()->attach(
            'Zend\View\Helper\Navigation\AbstractHelper', 
            'isAllowed', 
            array('\Application\Listener\RbacListener', 'accept')
        );
        $moduleRouteListener = new ModuleRouteListener();
        $moduleRouteListener->attach($eventManager);
    }
    
    public function accept(Event $event) { 
        $event->stopPropagation();
    
        $accepted = true;
    
        $serviceLocator = $event->getTarget()->getServiceLocator()->getServiceLocator();
        $rbac           = $serviceLocator->get('ZfcRbac\Service\Rbac');
    
        $params = $event->getParams();
        $page = $params['page'];
    
        $permission = $page->getPermission();
    
        if ($permission) {
            $accepted = $rbac->isGranted($permission);
        }
    
        return $accepted;
    }
    
    然后创建一个类
    Application\Listener\RbacListener
    ,如下所示:

    public function onBootstrap(MvcEvent $e)
    {
        $eventManager        = $e->getApplication()->getEventManager();
        $eventManager->getSharedManager()->attach(
            'Zend\View\Helper\Navigation\AbstractHelper', 
            'isAllowed', 
            array('\Application\Listener\RbacListener', 'accept')
        );
        $moduleRouteListener = new ModuleRouteListener();
        $moduleRouteListener->attach($eventManager);
    }
    
    public function accept(Event $event) { 
        $event->stopPropagation();
    
        $accepted = true;
    
        $serviceLocator = $event->getTarget()->getServiceLocator()->getServiceLocator();
        $rbac           = $serviceLocator->get('ZfcRbac\Service\Rbac');
    
        $params = $event->getParams();
        $page = $params['page'];
    
        $permission = $page->getPermission();
    
        if ($permission) {
            $accepted = $rbac->isGranted($permission);
        }
    
        return $accepted;
    }
    

    当您显示菜单时,它将根据权限和角色进行过滤,例如,如果您执行
    echo$this->navigation('navigation')->menu()
    然后只会显示用户有权限的菜单项。

    非常感谢您的回答,效果非常好。请您澄清一下$moduleRouteListener->attach($eventManager);我们为什么需要它?我尝试了您的解决方案@Mohammad,但出现了以下错误:严格的标准:call\u user\u func()要求参数1是有效的回调、非静态方法Application\Listener\RbacListener::accept()不应在第468行的/home/../zendframework/library/Zend/EventManager/EventManager.php中静态调用-当前版本有什么变化吗?以下是@Mohammed ZeinEddin使用最新版本ZF2和ZfcRbac的相同尝试的简短教程:RbacListener中的函数accept应该是静态的