Решение 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
}
}