Июль 112008
 

Источник: Zend_Acl and MVC Integration Part I (Basic Use)
Автор: Aldemar Bernal
Перевод: Лобач Олег

Итак, что не так с Zend_Acl и текущей реализацией MVC в Zend Framework? Ничего неправильного нет, просто не слишком очевидно для разработчиков, как достичь оптимальной интеграции между этими двумя важными частями фреймворка.

Во-первых, эта статья основана на следующем предложении (link), в настоящий момент находящемся в стадии Ожидания рекомендации.

Ну, как это работает? Существуют два основных компонента в этом предложении:

  1. Плагин фронт-контроллера (Front Controller Plugin): этот компонент решает, имеет ли доступ текущий пользователь к открываемой странице.
  2. Помощник действия (Action Helper): Этот компонент позволяет проверить, имеет ли текущий пользователь доступ внутрь контроллера.

Опираясь на эти два компонента, давайте попробуем их на примере. Давайте будем говорить о сайте, подобном DevZone. Нам потребуется контроллер для управления пользователями и еще один контроллер для управления статьями, так же 3 типа пользователей (ролей): одну для гостей, одну для авторов статей и еще одну для утверждения статей. Итого, мы имеем:

Ресурсы:

  1. Контроллер пользователей.
  2. Контроллер статей.

Роли:

  1. Гость (Guest).
  2. Автор (Writer).
  3. Администратор (Admin).

Настройка компонента Zend_Acl

После определения того, что нам нужно сделать, следующим шагом будет создание экземпляра Zend_Acl, отражающего нашу модель.

Создание ролей

Сейчас мы создадим роли в нашем экземпляре Zend_Acl.

Создание ресурсов

Создадим необходимые ресурсы (по одному на контроллер), а также их отношения с созданными нами ролями.

Создание привилегий

Теперь мы добавили роли и ресурсы в наш экземпляр Zend_Acl, пора объяснить, какие действия должны быть доступны для каких ролей.

  1. Гости не могут редактировать, добавлять и публиковать статьи.
  2. Авторы не могут публиковать статьи.
  3. Администраторы имеют полный доступ.

Создание страницы, отображаемой при отсутствии доступа

Нам нужно будет создать представление (view) и действие (action) на которое мы переадресуем всех пользователей, у которых недостаточно привилегий.
Во-первых, мы создадим новое действие в нашем контроллере ошибок:

Затем мы создадим наш файл представления (/application/views/scripts/error/denied.phtml) с некоторым предупреждающим сообщением:

Завершение настройки

Хорошо, мы настроили наш экземпляр Zend_Acl. Следующий шаг — регистрация плагина контроллера. Это важная часть берет созданный нами экземпляр Zend_Acl и проверяет, доступна ли текущая страница пользователю.

После завершения настройки, как только пользователь войдет в наше приложение, в зависимости от его/её роли будет либо отображена запрошенная страница, либо страница с сообщением о запрете доступа.

Для более подробного ознакомления с темой вы можете почитать следующее:
Zend_Acl & MVC Integration

и небольшой пример: Source Code

Похожие записи

  • http://podumaem.com Александр Махомет

    пишите полезную инфу, подберите скин для блога повеселее :)

  • http://lobach.info Лобач Олег

    «Полезную» это какую?

    А до скина уже с пол-года руки не доходят :(

  • Масанов

    Скинов полно для вордпресса. Просто дефолтный уже всем приелся.

  • http://lobach.info Лобач Олег

    Вот закрою текущий проект и займусь версткой скина...

  • tatarin

    Во первых когда скачал плагин и хелпер то они блин назывались не Zend_... а Zion_... пришлось все переименовывать,чтобы Zend_Loader::registerAutoload () работал((.Во вторых очень не нравиться то что для того чтобы обратиться к ЛЮБОМУ контроллеру(в понимании плогина как ресурса) приходится его объявлять как ресурс,а если скажем есть контроллер который всегда без всяких там прав должен открываться,ну хотя бы регистрация или еще что то там...Я поэтому решил скорректировать с децл код плагина (Zion_Controller_Plugin_Acl) — в методе preDispatch перед строчкой if (!$this->getAcl () ->isAllowed ($this->_roleName, $resourceName, $request->getActionName ())) поставил условие if ($this->getAcl () ->has ($resourceName)),чтобы проверить существует ли ресурс,теперь можно смело объявлять ресурсами только лишь те контроллеры на котроые действительно нужно контролить доступ.))))

  • tatarin

    кстати,у меня возникла проблема-не перехватывается процесс дисперетчизации если я использую хелпер Zend_View action,то есть проблема вот какая в скрипте вида пишу action ('say', 'say'); ?>,на который скажем гостю запрещен доступ,а он все равно ставновится виден...помогите пожаласта-не пойму че делать,чтобы ему доступ ограничивало)))

  • http://lobach.info Лобач Олег

    @tatarin: честно говоря, не совсем понятно что у Вас работает не так, как надо.

    Может быть опишете более подробно в чем проблема и сделаете архив с кодом, чтобы можно было посмотреть?

  • tatarin

    ок,вечером зайду и выложу весь код в архиве...ато голова уже болит...я в гугловской группе по зенд фреймворк уже выложил мессагу...пока никто не откликнулся...ну я там суть проблемы описал ==>

    В общем задача такая,чтобы мой плагин обошел все вызываемые пути,которые надо обработать в данном вызове,при запуске фронт контроллера(метод preDispatch в плагине) и просто их вывел......

    У меня такая проблема-вызывается помощник action action ('say', 'say'); ?> в скрипте вида say/index.tpl,тока вот почему то фронт контроллер не воспринимает то что запрос идет к say/say (в нашем случае из помощника action) а не к say/index (контроллер/действие)...объясните почему это и как это обойти...или я че то путаю?Может тут поможет ActionStack-я правда ничего не знаю о нем,но название такое что он в себе содержит вроде все запросы которые обработались по одному маршруту(в моем случае их 2-say/index и say/say).

    Моя логика-он должен вывести по маршруту cs/say

    --say/index

    --say/say

    А выводит зараза совсем нито))

    Тут может еще preDispatch у всех контроллеров надо перегрузить,чтобы они ловили все вызовы к ним,но нельзя ли обойтись как нить без этого?

  • http://lobach.info Лобач Олег

    Это ведь плагин контроллера. А для решения Вашей задачи может стоит написать (или расширить стандартный) вью хелпер?

  • http://lobach.info Лобач Олег

    пришлось расширять класс Zend_Controller_Action

    На мой взгляд вполне нормальное решение. Что в нем плохого?

  • tatarin

    Ну еще добавлю по проблеме:

    данный плагин позволяет отслеживать доступ только лишь к тому маршруту,который задается через урл(при инстанировании фронт контроллера),а теперь представьте себе ,что мы запросили контроллер и дейтсвие через урл к которому доступ открыт,а вот в виде контроллера вызывается хелпер action ('действие к которому нельзя получить доступ','контроллер к которому нельзя получить доступ') -так вот метод преддиспетчиризации в плагине не ловит этого и поэтому выводится содержимое запрещенного маршрута...поэтому в моей ситуации этот плагин оказался бесполезным(я роюсь уже 4 дня как все заствить это работать),так как вроде как он и не может ловить все маршруты вызываемые в процессе диспетчиризации...пришлось расширять класс Zend_Controller_Action и от него наследовать все остальные контроллеры...если вы разберетесь с этим и выложите идеи как ловить все маршруты то напишите,буду благодарен)))

  • http://lobach.info Лобач Олег

    если надо класс кстати могу выложить))

    Ну, хуже от этого не будет ;)

  • tatarin

    Ну плохого вобщем то ничего нет...))Просто я ожидал что этот плагин выполнит то что о нем говорится(как только пользователь войдет в наше приложение, в зависимости от его/её роли будет либо отображена запрошенная страница, либо страница с сообщением о запрете доступа)...на счет вью-хелпера-это не то-придется постоянно его вызывать,а хочу чтобы все было автоматом-указал в файле настроек все и чтоб работало без лишнего кода...кстати когда писал класс возник интересный вопрос-

    почему _forward в init () выдает ошибку

    string (2092) "ERROR: Action «denied» does not exist and was not

    trapped in __call ()

    0 Z:homecswwwlibsZendControllerAction.php (518):

    Zend_Controller_Action->__call ('deniedAction', Array)

    а если я его использую в init (),а если использую в preDispatch () то

    все работает как надо?

  • tatarin

    если надо класс кстати могу выложить))

  • tatarin

  • tatarin

    кстати он не так работает когда идет пересыл в хелпере action-он вообще ничего не показывает если доступ запрещен вместо перенаправления...я не знаю почему...помогите если кто понимает в этом че))я вот уже голову сломал пока думал...просто берет и ничего не показывает...

  • http://zendframework.ru Александр Махомет

    >>“Полезную” это какую?

    Имел ввиду пИшите, не призыв а констатация факта. А обложка, то есть скин блога, не привлекательная.

  • http://lobach.info Лобач Олег

    Имел ввиду пИшите, не призыв а констатация факта.

    Я действительно понял фразу как призыв.

    А обложка, то есть скин блога, не привлекательная.

    Да мне и самому не очень нравится, но до верстки нормального шаблона все никак руки не доходят.

  • http://zendframework.ru Александр Махомет

    Да мне и самому не очень нравится, но до верстки нормального шаблона все никак руки не доходят.

    Есть ведь масса других уже готовых шаблонов, скачал, залил, включил и может даже сразу работать :) в гугле очень быстро находятся www.google.com/search?hl=...оны+wordpress

  • http://zendframework.ru Александр Махомет

    Кстати рекомендую поставить премодерирование только на первый комментарий с одного email. Так отсекается большая часть спамеров, а постоянные посетители сразу размещают комментарии, и общение более живое.

  • http://thisbook.info Dima

    Подскажите, какую нибудь статью, как бы это еще все к базе данных прикрепить

  • http://lobach.info Лобач Олег

    Подскажите, какую нибудь статью, как бы это еще все к базе данных прикрепить

    По подробней опишите задачу: что именно прикрепить к БД?

    • http://excalibur.com.ua excalibur

      Интерфейс для администратора по управлению прав групп пользователей случайно не разрабатывали? Конечно связка Zend_Acl+Zend_Db должна быть обязательно, но нужно это еще грамотно спроектировать, а ссылка ниже на связку пока не очень во многом помогла.

      • http://lobach.info Лобач Олег

        А в чем проблема с интерфейсом администратора? Это же простейший CRUD

  • http://thisbook.info Dima

    Имел ввиду, есть как нибудь наиболее оптимальные способы подгружать Acl динамически

  • http://lobach.info Лобач Олег

    http://yandex.ru/yandsearch?text=zend_acl+db

    И первая же ссылка ведет на простейший пример реализации хранения ACL в БД — my.opera.com/zomg/blog/20...esources-in-a-db

    Ну а оптимальность того или иного решения зависит от конкретной задачи и условий

  • http://lobach.info Лобач Олег

    Кстати, в комментариях к той статье есть ссылка на готовый класс (наследник Zend_ACL), использующий БД для хранения правил — www.phpclasses.org/browse/package/4100.html

  • http://thisbook.info Dima

    Спасибо, очень признателен.

  • http://lobach.info Лобач Олег

    Хорошо, если я смог помочь