Zend Navigation и RBAC

Я разрабатываю сайт на основе ZF2. У меня есть основная навигация, которая остается неизменной независимо от статуса посетителя/пользователя. Необходимо добавить еще один компонент/навигацию, который будет зависеть от статуса и роли пользователя. Для посетителя предметы будут

  • регистр
  • Авторизоваться
  • EN (фактически раскрывающийся список с другим доступным языком)

Для вошедшего в систему обычного пользователя он будет отображать

  • Профиль
  • Выйти
  • EN (селектор языка, как указано выше)

А для некоторых пользователей с определенными ролями/разрешениями будут дополнительные пункты

Я хочу использовать RBAC, так как ACL кажется раздутым, а также просто проверить, есть ли у текущего вошедшего в систему пользователя/роли дополнительные элементы, мне нужно загрузить полный ACL (и у нас есть около 15+ различных типов ролей).

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

  1. Я создаю пустой навигационный контейнер и создаю фабрику. На фабрике я получаю доступ к аутентификации и RBAC и добавляю страницы в зависимости от статуса/роли пользователя.
  2. Я создаю полностью загруженную навигацию со всеми возможными страницами, затем в заводских условиях с помощью Аутентификации и RBAC скрываю страницы, которые не хочу показывать.
  3. Вариант rd — использовать помощник представления, который получит RBAC через ServiceLayer и сгенерирует навигацию. (Как обсуждалось в ZF2, как отображать твиты в макете и ZF2: добавьте виджет входа в шаблон.

  4. Или я могу создать плагин-контроллер или просто метод в module.php и прослушать событие MVC_Render или MVC_Dispatch, сгенерировать желаемую навигацию и добавить вывод в переменную представления.

PS: мне нужно использовать частичное, так как мне нужно добавить класс CSS в раздел выбора языка. Также в макете будет отображаться навигация.


person M Hill    schedule 22.09.2013    source источник


Ответы (1)


Я использую ZfcRbac и делаю это следующим образом: вы можете отображать навигацию в зависимости от пользователя роли и разрешения элементов навигации следующим образом:

Сначала добавьте разрешение к элементу навигации следующим образом:

'permission' => 'edit-profile',

Затем подключите прослушиватель в onBootstrap следующим образом:

public function onBootstrap(MvcEvent $e)
{
    $eventManager        = $e->getApplication()->getEventManager();
    $eventManager->getSharedManager()->attach(
        'Zend\View\Helper\Navigation\AbstractHelper', 
        'isAllowed', 
        array('\Application\Listener\RbacListener', 'accept')
    );
    $moduleRouteListener = new ModuleRouteListener();
    $moduleRouteListener->attach($eventManager);
}

Затем создайте класс Application\Listener\RbacListener следующим образом:

public function accept(Event $event) { 
    $event->stopPropagation();

    $accepted = true;

    $serviceLocator = $event->getTarget()->getServiceLocator()->getServiceLocator();
    $rbac           = $serviceLocator->get('ZfcRbac\Service\Rbac');

    $params = $event->getParams();
    $page = $params['page'];

    $permission = $page->getPermission();

    if ($permission) {
        $accepted = $rbac->isGranted($permission);
    }

    return $accepted;
}

и благодаря этому, когда вы отображаете меню, оно будет отфильтровано на основе разрешений и ролей, например, если вы сделаете echo $this->navigation('navigation')->menu(), будут отображаться только те пункты меню, на которые у пользователя есть разрешение.

person Mohammad ZeinEddin    schedule 22.09.2013
comment
Большое спасибо за ваш ответ, работает как шарм. Не могли бы вы немного пояснить о $moduleRouteListener-›attach($eventManager); Почему нам это надо? - person write2art; 24.04.2014
comment
Я пробовал ваше решение @Mohammad, но получаю следующую ошибку: Строгие стандарты: call_user_func() ожидает, что параметр 1 будет допустимым обратным вызовом, нестатический метод Application\Listener\RbacListener::accept() не должен вызываться статически в /home /.../zendframework/library/Zend/EventManager/EventManager.php в строке 468 — Что-то изменилось в текущих версиях? - person webDEVILopers; 02.06.2014
comment
Вот краткое руководство по той же попытке @Mohammed ZeinEddin, которая работает с последними версиями ZF2 и ZfcRbac: blog.webdevilopers.net/?p=9 - person webDEVILopers; 03.06.2014
comment
функция accept в RbacListener должна быть статической - person Ronnie; 18.06.2014