【问题标题】:ZEND_ACL solution in the module based application基于模块的应用程序中的 ZEND_ACL 解决方案
【发布时间】:2013-01-31 16:10:18
【问题描述】:

我正在 ZF 上开发一个应用程序。

我遇到了一个巨大的无法解决的问题 - ZEND_Acl

这对我来说是无法解决的,因为我发现的每篇文章都与基于 MODULE 的应用程序无关。

最近我发现packtpub article 描述了在模型中使用 ACL

但它看起来很复杂,很复杂,不是我一直在寻找的那个。

它有 StoreFront - 一切都在那里,在我的例子中,我把所有东西都分成了模块。

我在许多其他来源以及文档中看到了 ACL 实现技术。

我不知道如何解决以及从哪里开始(实际上是如何)开发/构建我的 ACL 实现。

我的应用程序如下所示:

application/ 
       configs/
       layouts/
               master.phtml
               admin.phtml
       modules/
               users/
                    controllers/
                                adminController
                                indexContoller
                    models/
                    views/
               blog/
                    controllers/
                                adminController
                                indexController
                    models/
                    views/
               orders/
                    controllers/
                                adminController
                                indexController
                    models/
                    views/

如您所见,我在 adminControllers 中有管理功能,在 indexControllers 中有前端功能。

在模块内部拥有 adminControllers 和视图的想法是拥有分散的模块架构,而不是为管理员创建单独的模块。

现在我想为我的应用程序实现 ACL。

通常我会有管理员 - 超级管理员、编辑、发布者 - 管理员将访问所有 adminControllers 但每个都是 action 并且肯定用户无法访问 adminControllers。

和用户 - 访客、注册、付费,因此层次结构看起来像这样:

$acl = new Zend_Acl();
$acl->addRole(new Zend_Acl_Role('visitor')); 
$acl->addRole(new Zend_Acl_Role('registered'), 'visitor');
$acl->addRole(new Zend_Acl_Role('paid'), 'registered');
$acl->addRole(new Zend_Acl_Role('publisher'), 'paid');
$acl->addRole(new Zend_Acl_Role('editor'), 'publisher');
$acl->addRole(new Zend_Acl_Role('superadmin'), 'editor');  

此层次结构可跨应用程序使用。

目标是在每个模块中写入写入权限和资源,这样当特定项目不存在某些模块时,我可以避免在我的 ACL 文档中出现垃圾。

我还没有在 YouTube 上测试 Alexander Romanenko 教程的方法,但是在开发 ACL 时,他从 FrontController 插件加载 ACL - 我的情况是什么方法?

在实现 ACL 时,我必须考虑到 ACL 动态断言,以备将来使用。而像“VISITORS”这样的时刻不能发cmet,注册用户也不能在博客中看到付费文章。

也许您可以帮助我将 ACL 集成到我的项目中,也许您知道在哪里可以找到 HOW TO 并按照说明进行操作的好资源。

编辑

具有 ACL 的 preDispatch() 的控制器插件将用于每个模块(在本例中为用户)(对吗?)

我尝试在模块的 (USERS) 引导程序中自动加载插件:

$plugin = Zend_Controller_Front::getInstance();
$plugin->registerPlugin(new Users_Plugin_AccessCheck());

但似乎整个应用程序都需要这个插件并给出错误:

Fatal error: Uncaught exception 'Zend_Session_Exception' with message 'Session must be started before any output has been sent to the browser; output started in H:\Server\xampp\htdocs\c2g\application\modules\users\plugins\AccessCheck.php/6' in H:\Server\xampp\htdocs\c2g\library\Zend\Session.php:451 Stack trace: #0 ... So on

我认为这是因为插件加载了两次。但是,除了模块 (USERS) 本身之外,每个页面都会发生这种情况。

【问题讨论】:

    标签: zend-framework zend-auth zend-acl zend-framework-modules


    【解决方案1】:

    我在我的一个应用程序中使用了类似的结构,因此希望我可以为您指明正确的方向。我的设置方式是:

    • 在我的主应用程序引导程序中初始化角色(这是您在问题中包含的代码),将 Zend_Acl 对象存储在注册表中以便在其他地方访问
    • 每个模块引导程序设置自己的 ACL 资源并定义哪些角色可以访问什么
    • ACL 检查是使用控制器插件完成的。

    资源名称只是任意字符串,因此只要您遵守约定,您就可以在插件中自动执行 ACL 检查。例如,假设您想要的只是每个模块的索引和管理控制器的资源。在每个模块引导程序中,您都有以下内容:

    protected function _initAcl()
    {
        $acl = Zend_Registry::get('acl');
    
        $frontendResource = new Zend_Acl_Resource('users');
        $adminResource = new Zend_Acl_Resource('users-admin');
    
        $acl->addResource($frontendResource);
        $acl->addResource($adminResource);
    
        // allow everyone frontend access
        $acl->allow('visitor', $frontendResource);
    
        // admins only for admin access
        $acl->allow('superadmin', $adminResource);
    }
    

    然后在您的 ACL 控制器插件中,通过检查请求对象来计算资源名称并执行检查:

    public function preDispatch(Zend_Controller_Request_Abstract $request)
    {
        $acl = Zend_Registry::get('acl');
    
        $currentResource = $request->getModuleName().'-'.$request->getControllerName();
        if ($acl->has($currentResource) && !$acl->isAllowed($user->role, $currentResource)) {
            // permissions error
        }
    }
    

    【讨论】:

    • 非常感谢您的回答,蒂姆。现在我被鼓励最终实现 ACL :) 经您的许可,我想问您几个问题,首先我要编辑我的问题,并检查一下。
    • 现在经过思考,我开始分析您在回答中告诉我的内容。您能否更详细地说明您的实施方式。我的意思是你正在使用的文件的路径和里面的类:smth like: path: application/controllers/plugins/AclPlugin.php \n class: Plugin_AclPlugin extens Zend_Controller_Plugin_Abstract 谢谢!
    • 是的,您只有一个控制器插件。我住在application/plugins/Acl.php
    • 好吧,我想通了。感谢帮助。我还有 1 个问题。当用户访问特定模块时,引导程序将资源和权限写入注册表中的 $acl。当用户通过 2 个模块时,步骤是 MODULE 1 写入其 ACL,当用户访问 MODULE 2 时,它也写入其 ACL。所以,我的问题是 - $ACL 不会被这么多的资源和权限记录超载吗?你清洗它吗?此外,还有一些我正在调用的跨模块操作,例如。默认情况下,我想调用用户模块中的注销 - 那你会做什么?
    • 我在添加大量资源时没有遇到任何问题 - 资源类相当轻量级。我使用此设置的应用程序有大约 20-25 个模块。不知道你说的第二部分是什么意思。所有模块引导程序都会针对每个请求运行,您的所有模块资源将始终存在。因此,您应该可以轻松地检查其他模块的权限。
    猜你喜欢
    • 1970-01-01
    • 2012-02-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-05
    • 2012-01-30
    • 1970-01-01
    相关资源
    最近更新 更多