Zend Navigation: где я должен загрузить ACL 'Role' в частном приложении - PullRequest
3 голосов
/ 29 апреля 2011

Я работаю над «частным» приложением, вы должны войти в систему, чтобы что-то делать вообще.Это дает мне небольшую проблему при загрузке роли для Zend Navigation.В настоящее время я запускаю Zend Navigation в моей начальной загрузке;это было нормально, пока я не добавил ACL в Zend Nav.Проблема в том, что я хочу загрузить 'userRole' из моего хранилища аутентификации, но пока пользователь не войдет в систему, пока не будет хранилища, поэтому я получаю предупреждение «Попытка получить свойство не-объекта» на странице входа в систему.,Это связано с тем, что перед входом в систему ничего нет в хранилище аутентификации, поэтому auth->userRole - это «ничто», потому что auth->getInstance()->getIdentity()->??? будет пустым, пока пользователь не войдет в систему и не настроит аутентификацию.

Я неиспользуя Zend Nav на странице входа в систему, на самом деле у меня есть альтернативный макет страницы входа в систему (вообще нет навигации);'if !$auth->hasIdentity' (false) использовать макет входа в систему, показывать только страницу входа для всей системы, как я уже говорил, приложение полностью закрытое, поэтому использование по умолчанию роли «гость» или что-то подобное выглядит как «грязный» подходпотому что, как только пользователь войдет в систему, ему все равно придется перенастроить аутентификацию.Просто кажется неправильным устанавливать общую аутентификационную идентификацию только для того, чтобы угодить странице входа в систему.

Что я получаю, так это то, где хорошее место для перемещения 'init' Zend Nav, или вхотя бы переместить часть настройки ACL?Можно ли переместить все это?

Это то, что у меня есть в моем bootstrap.php для Zend Navigation:

protected function _initNavigation() {
    $this->_logger->info('Bootstrap ' . __METHOD__);

    $this->bootstrap('layout');
    $layout = $this->getResource('layout');
    $view = $layout->getView();
    $config = new Zend_Config_Xml(APPLICATION_PATH . '/configs/navigation.xml', 'nav');
    $container = new Zend_Navigation($config);
    $acl = new Application_Model_Acl_Acl();
    $role = Zend_Auth::getInstance()->getIdentity()->userRole;
    $view->navigation($container)->setAcl($acl)->setRole($role);
}

Это '$role = Zend_Auth::getInstance()->getIdentity()->userRole', что пусто (или не-объект) во время запуска начальной загрузки.

Весь мой ACL происходит либо в контроллере (в действии), либо в какой-то момент может происходить в моделях, хотя я не ожидаю веб-службыили что-то еще, так что, может быть, они останутся в контроллере, но у меня есть гибкость, потому что у меня есть ACL в моделях (это было бы правильно "домен"?

Я использую ACL только в Zend Nav длямакет, цели взаимодействия с пользователем; меню и ссылки, которые я получаю от Zend Nav, будут «серыми», несуществующими или активными (и видимыми) в зависимости от роли пользователя, например, роль «пользователя» не получит много «admin»'опций, и это подтверждается ACL в контроллере, поэтому нельзя просто ввести URL-адрес и попасть в область.

Моя другая мысль заключалась в том, что, возможно, мне следует подумать о переносе своего логина вгоСамозагрузка для этой ситуации, но я не уверен, что это тоже хорошая идея?


РЕДАКТИРОВАТЬ: Это код, который я вставил в плагин Front Controller:

class Plugins_Controller_ZendNavInit extends Zend_Controller_Plugin_Abstract {

        public function preDispatch(Zend_Controller_Request_Abstract $request) {

            $auth = Zend_Auth::getInstance();

            if ($auth->hasIdentity()) {

                $config = new Zend_Config_Xml(APPLICATION_PATH . '/configs/navigation.xml', 'nav');
                $container = new Zend_Navigation($config);
                $acl = new Application_Model_Acl_Acl();

                $layout = Zend_Layout::getMvcInstance();
                $view = $layout->getView();

                $role = Zend_Auth::getInstance()->getIdentity()->userRole;
                $view->navigation($container)->setAcl($acl)->setRole($role);
            }
        }
    }

Прекрасно работает;Я, конечно, должен был зарегистрировать свой плагин, как и любой другой.Я также перенес проверку Auth на плагин фронт-контроллера.

Ответы [ 2 ]

3 голосов
/ 29 апреля 2011

Вы можете создать анонимную роль перед входом в систему и обработать очень короткую политику ACL для анонимных пользователей. Проверьте этот ответ , например, о том, как отловить неаутентифицированных пользователей в PreDispatch с плагином Auth.

1 голос
/ 23 июля 2011

Я бы не вытащил его напрямую из хранилища аутентификации.Если вы извлекаете его из Zend_Auth и во время этого сеанса пользователя изменяется роль пользователя, вам придется либо принудительно выйти из системы / войти в систему, либо обновить информацию в хранилище Zend_Auth.Мне проще настроить класс Role и выполнить логику, чтобы определить роль там или установить роль по умолчанию (guest).Класс роли User расширяет мою модель User и реализует Zend_Acl_Role_Interface.Затем я могу запросить БД из класса Role.Я начал реализовывать это примерно день назад, но вот пример:

<?php

класс Zfcms_Acl_Role_User расширяет Zfcms_Model_Users реализует Zend_Acl_Role_Interface {

/**
 * Unique id of Role
 *
 * @var string
 */
protected $_roleId;
public $_inheritsFrom = 'guest';
public $_defaultRole = 'user';

/**
 * Sets the Role identifier
 *
 * @param  string $id
 * @return void
 * Defined by Zend_Acl_Role_Interface; returns the Role identifier
 *
 * @return string
 */
public function getRoleId()
{
    //$auth = Zend_Auth::getInstance();
    if(Zend_Auth::getInstance()->hasIdentity()) 
    {
        $this->_roleId = self::getUserRoleById(Zend_Auth::getInstance()->getIdentity()->user_id);
        return $this->_roleId;
    } 
    elseif(!Zend_Auth::getInstance()->hasIdentity() && !isset($this->role))
    {
        //return 'guest';
        return (string) new Zfcms_Acl_Role_Guest();
    } else {
        throw new Zend_Controller_Action_Exception('Invalid user roleId', 110);
    }
}
public function getDefaultRole()
{
    return $this->_defaultRole;
}
public function getPrivsByRole($role)
{
   //TODO: Design db table to hold privs
}
private function setPrivs()
{
   //TODO: implement
}
/**
 * Defined by Zend_Acl_Role_Interface; returns the Role identifier
 * Proxies to getRoleId()
 *
 * @return string
 */
public function __toString()
{
    return $this->getRoleId();
}
public function getUserRoleById($id)
{
    $this->_id = $id;
    $query = $this->select()
                  ->from('users', array('user_id', 'role'))
                  ->where('user_id = ?', $this->_id);

    $result = $this->fetchAll($query);
    foreach($result as $userRole)
    {
        $role = $userRole->role;
    }
    return $role;
}

}

...