Решение ZEND_ACL в модульном приложении

Я разрабатываю приложение на ZF.

Я столкнулся с огромной неразрешимой проблемой - ZEND_Acl

Это неразрешимо для меня, потому что каждая найденная статья не относится к приложениям на основе MODULE.

В последнее время я обнаружил статью в packtpub, в которой описано использование 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 для моего приложения.

обычно у меня есть администраторы - superadmin, Editor, Publisher - администраторы, которые будут иметь доступ ко всем 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, но при разработке ACL он загружает ACL из плагина FrontController - какой подход будет в моем случае?

И при реализации ACL я должен принять во внимание динамические утверждения ACL на будущее. А такие моменты, как "ПОСЕТИТЕЛИ", не могут оставлять комментарии, а пользователи, находящиеся в поиске, не могут видеть оплаченные статьи в блоге.

Может быть, вы можете помочь мне интегрировать ACL в мой проект, может быть, вы знаете хорошие ресурсы, где найти КАК и следовать инструкциям.

РЕДАКТИРОВАТЬ

Плагин Controller, который будет иметь preDispatch() из ACL, будет для каждого модуля (в данном случае USERS) (верно?)

Я попытался автоматически загрузить плагин в модуле (USERS) Bootstrap:

$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

Я думаю, это потому, что плагин загружается дважды. Но это происходит на каждой странице, кроме самого модуля (ПОЛЬЗОВАТЕЛИ).

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
    }
}
Другие вопросы по тегам