Zend_Auth лучшие практики - PullRequest
5 голосов
/ 01 апреля 2011

Моя цель - требовать входа на определенные страницы. Я использую Zend Framework MVC и пытаюсь найти примеры лучших практик.

Некоторые заметки о том, что я ищу:

  • Я хочу, чтобы пользователи, не вошедшие в систему, получили окно входа в систему, а затем вернулись к зарегистрированной версии страницы после проверки подлинности
  • Я хочу использовать внедрение зависимостей и избегать синглетонов
  • Небольшой кодовый код - привязать к структуре Zend mvc
  • Должно ли поле для входа быть отдельным контроллером и выполнять перенаправление заголовка? Как вернуться на целевую страницу после успешного завершения? Идея просто вызвать действие контроллера входа в систему, чтобы отобразить поле входа в систему на целевой странице, или это недостаток в индексации поисковой системы?
  • Уметь использовать внешнюю библиотеку для обработки куки

Или что-то совершенно другое. Я довольно плохо знаком с фреймворком Zend и хочу сделать это «правильным образом».

Ответы [ 3 ]

4 голосов
/ 02 апреля 2011

Вы можете использовать комбинацию Zend_Auth и Zend_Acl . Чтобы расширить другие ответы, я приведу краткий пример того, как вы можете управлять аутентификацией с помощью Zend Framework:

Сначала необходимо установить плагин для predispatch всех запросов и проверить, разрешен ли клиенту доступ к определенным данным. Этот плагин может выглядеть так:

class Plugin_AccessCheck extends Zend_Controller_Plugin_Abstract {

    private $_acl = null;

    public function __construct(Zend_Acl $acl) {
        $this->_acl = $acl;
    }

    public function preDispatch(Zend_Controller_Request_Abstract $request) {
        //get request information
        $module = $request->getModuleName ();
        $resource = $request->getControllerName ();
        $action = $request->getActionName ();

        try {
            if(!$this->_acl->isAllowed(Zend_Registry::get('role'), 
                                $module . ':' . $resource, $action)){
                $request->setControllerName ('authentication')
                        ->setActionName ('login');
            }
        }catch(Zend_Acl_Exception $e) {
            $request->setControllerName('index')->setActionName ('uups');
        }
    }
}

Таким образом, каждый тип пользователя имеет определенные разрешения, которые вы определяете в своей библиотеке acl. При каждом запросе вы проверяете, имеет ли пользователь доступ к ресурсу. Если вы не перенаправляете на страницу входа, иначе preDispatch передает пользователя на ресурс.

В Zend_Acl вы определяете роли, ресурсы и разрешения, которые разрешают или запрещают доступ, например ::

class Model_LibraryAcl extends Zend_Acl {
    public function __construct() {

        $this->addRole(new Zend_Acl_Role('guests'));
        $this->addRole(new Zend_Acl_Role('users'), 'guests');
        $this->addRole(new Zend_Acl_Role('admins'), 'users');                

        $this->add(new Zend_Acl_Resource('default'))
             ->add(new Zend_Acl_Resource('default:authentication'), 'default')
             ->add(new Zend_Acl_Resource('default:index'), 'default')
             ->add(new Zend_Acl_Resource('default:error'), 'default');

        $this->allow('guests', 'default:authentication', array('login'));
        $this->allow('guests', 'default:error', 'error');

        $this->allow('users', 'default:authentication', 'logout');          
    }
}

Затем вам нужно настроить acl и auth в вашем файле начальной загрузки:

    private $_acl = null;

    protected function _initAutoload() {

       //...your code           
       if (Zend_Auth::getInstance()->hasIdentity()){
        Zend_Registry::set ('role',
                     Zend_Auth::getInstance()->getStorage()
                                              ->read()
                                              ->role);
        }else{
            Zend_Registry::set('role', 'guests');
        }

        $this->_acl = new Model_LibraryAcl ();
        $fc = Zend_Controller_Front::getInstance ();
        $fc->registerPlugin ( new Plugin_AccessCheck ( $this->_acl ) );

        return $modelLoader;
    }

Наконец, в вашем контроллере аутентификации вы должны использовать пользовательский адаптер аутентификации и настроить действия для входа и выхода:

public function logoutAction() {
    Zend_Auth::getInstance ()->clearIdentity ();
    $this->_redirect ( 'index/index' );
}

private function getAuthAdapter() {
    $authAdapter = new Zend_Auth_Adapter_DbTable ( 
                        Zend_Db_Table::getDefaultAdapter ());
    $authAdapter->setTableName('users')
                ->setIdentityColumn('email')
                ->setCredentialColumn ('password')
                ->setCredentialTreatment ('SHA1(CONCAT(?,salt))');

    return $authAdapter;
}

При входе в систему вам необходимо передать данные для входа в адаптер авторизации, который выполняет аутентификацию.

$authAdapter = $this->getAuthAdapter ();
$authAdapter->setIdentity ( $username )->setCredential ( $password );
$auth = Zend_Auth::getInstance ();
$result = $auth->authenticate ( $authAdapter );

if ($result->isValid ()) {
    $identity = $authAdapter->getResultRowObject ();
    if ($identity->approved == 'true') {
        $authStorage = $auth->getStorage ();
        $authStorage->write ( $identity );
        $this->_redirect ( 'index/index' );
    } else {
       $this->_redirect ( 'authentication/login' );
  }

И это все. Я рекомендую вам это КАК на YouTube на Zend Auth и Zend ACL.

4 голосов
/ 01 апреля 2011
  • Я хочу, чтобы незарегистрированные пользователи получили окно входа в систему, а затем вернулись в зарегистрированный в версии страницы, один раз проверка подлинности

Используйте плагин FrontController и перенаправьте или перенаправьте их на страницу входа.

  • Я хочу использовать внедрение зависимостей и избегать синглетонов

Zend Framework, в настоящее время не поставляется с какой-либо системой DI, однако Zend_Application_Resource_ * фактически заменяет ее. Какая зависимость вам нужна здесь?

  • Маленький кодовый код - привязать к структуре Zend mvc

Это зависит от вас.

  • Должно ли поле для входа быть отдельным контроллером и выполнять перенаправление заголовка? Как вернуться на целевую страницу после авторизации успех? Идея просто позвонить действие контроллера входа в систему для отображения поле входа на целевой странице или это недостаток в отношении поиска индексация двигателя?

В основном я использую специальный AuthController с LoginAction & LogoutAction. Чтобы перенаправить пользователя на страницу, которую он пытался просмотреть, я всегда добавляю элемент returnUrl в свои формы и вставляю значение запрошенного URL, чтобы иметь возможность перенаправить пользователя, и если его нет, я перенаправляю его индекс / панель инструментов, зависит.

  • Уметь использовать внешнюю библиотеку для обработки куки

Zend_Auth позволяет вам установить собственный механизм хранения , поэтому просто реализуйте интерфейс.

$auth = Zend_Auth::getInstance();
$auth->setStorage(new My_Auth_Storage());

Но никогда не сохраняют результат аутентификации в файле cookie, его так легко изменить и получить доступ к вашему веб-сайту.

Вы также можете взглянуть на один из моих предыдущих ответов .

1 голос
/ 01 апреля 2011

Не уверен, что это лучшая практика, но если бы я реализовал то, что вы хотите, я бы сделал следующее:

  1. Создайте LoginForm с уникально идентифицируемой кнопкой отправки (объяснено позже)
  2. Создайте AuthService с методами getLoginForm, login, logout и одним или всеми из: getIdentity, hasIdentity и аналогичными методами.
  3. Создайте viewhelper, который имеет экземпляр этой службы, и в зависимости от того, каков результат hasIdentity, либо визуализируйте LoginForm, либо предоставьте идентификацию вошедшего в систему пользователя, в представлениях, которым требуется эта функциональность.
  4. Создайте плагин фронт-контроллера, который также имеет экземпляр службы, и реализуйте подключаемый модуль preDispatch.Дайте ему некоторый конфиг, какие действия исследовать.Если AuthService->hasIdentity() вернет true, ничего не делать.Если запрос является пост-запросом, ищите уникально идентифицируемое имя кнопки отправки, то есть: $request->getPost( 'loginSubmitButton', null ); по умолчанию null, если не доступно.Если нет null, сделайте login( $request->getPost() ) на службе.В случае успеха перенаправьте на то же действие, в случае неудачи провалите и снова визуализируйте форму в окне просмотра (автоматически отображая ошибки).

Служба может быть получена как из окна просмотра, так и из фронт-контроллераплагин с каким-то локатором службы, выполняющим что-то вроде ServiceAbstract::getService( 'Auth' ), регистрируя службу в ServiceAbstract в загрузчике.

...