ZF3 предоставляет специальный компонент Zend\Permissions\Rbac, реализующий контейнер для ролей и привилегий.
Для установки компонента Zend\Permissions\Rbac в ваше веб-приложение, воспользуйтесь следующей командой:
php composer.phar require zendframework/zend-permissions-rbac
Роль – это группа пользователей. Например, в приложении Blog могут быть следующие роли: Viewer (читатель), Author (автор), Editor (редактор) и Administrator (администратор).
| Имя роли | Описание |
|---|---|
Viewer |
Может читать любой пост. |
Author |
Может просматривать посты, а также создавать их, редактировать и опубликовывать. |
Editor |
Может просматривать посты, а также редактировать и опубликовывать их. |
Administrator |
Может делать все то же, что могут Viewer и Editor, а также удалять посты. |
Пользователю может быть присвоена одна или несколько ролей. Например, пользователь Иван может быть одновременно и читателем и редактором.
Роль может наследовать привилегии от других ролей. Другими словами, роли можно организовать в иерархию, в которой родительские роли наследуют привилегии дочерних. Например, в нашем приложении Blog роль Administrator будет наследовать привилегии от роли Editor (см. рисунок 17.1 ниже). Это обусловлено тем, что администратор может делать все то же, что и редактор, плюс удалять посты. Роли Editor и Author будут наследовать привилегии от роли Viewer.
Рисунок 17.1 Иерархия ролей на сайте Blog
Роли могут быть присвоены несколько привилегий. Привилегия – это типовое действие в системе. Ниже приведены несколько примеров привилегий на сайте Blog:
| Имя привилегии | Описание |
|---|---|
post.view |
Просматривать любой пост. |
post.edit |
Редактировать любой пост. |
post.own.edit |
Редактировать только собственные посты. |
post.publish |
Опубликовывать любой пост. |
post.own.publish |
Опубликовывать только собственные посты. |
post.delete |
Удалять любой пост. |
Например, роли Viewer будет присвоена привилегия post.view. Роли Editor будут присвоены привилегии
post.edit и post.publish. Роли Author будут присвоены привилегии post.own.edit и post.own.publish.
Наконец, роли Administrator будет присвоена привилегия post.delete.
В ZF3 в качестве контейнера для ролей и привилегий можно использовать класс Rbac из пространства имен Zend\Permissions\Rbac.
С помощью этого контейнера вы можете хранить в памяти роли, организованные в иерархию, и с присвоенными им привилегиями.
В качестве примера, создадим контейнер Rbac для приложения Blog и заполним его ролями и привилегиями:
use Zend\Permissions\Rbac\Rbac;
// Создаем новый контейнер Rbac.
$rbac = new Rbac();
// Сообщаем Rbac, что нужно создать родительские роли, если их еще нет
$rbac->setCreateMissingRoles(true);
// Создаем иерархию ролей
$rbac->addRole('Viewer', ['Editor', 'Author']);
$rbac->addRole('Editor', ['Administrator']);
$rbac->addRole('Author');
$rbac->addRole('Administrator');
// Присваиваем привилегии роли Viewer.
$rbac->getRole('Viewer')->addPermission('post.view');
// Присваиваем привилегии роли Author.
$rbac->getRole('Author')->addPermission('post.own.edit');
$rbac->getRole('Author')->addPermission('post.own.publish');
// Присваиваем привилегии роли Editor.
$rbac->getRole('Editor')->addPermission('post.edit');
$rbac->getRole('Editor')->addPermission('post.publish');
// Присваиваем привилегии роли Administrator.
$rbac->getRole('Administrator')->addPermission('post.delete');
Как видите, роль добавляется в контейнер Rbac с помощью метода addRole(). Этот метод
принимает два аргумента: имя роли, которую мы хотим создать, и имя (или имена) ее родительской
роли (или родительских ролей). Если родительских ролей еще не существует, они создаются
автоматически (для этой цели используется метод setCreateMissingRoles()).
Привилегии присваиваются созданной роли с помощью метода роли addPermission().
После того, как вы настроите контейнер, вы можете запросить информацию о том, имеет ли
роль определенную привилегию. Сделать это можно с помощью метода isGranted(), как показано ниже:
// Метод ниже вернет false, так как читатель не может удалять посты
$rbac->isGranted('Viewer', 'post.delete');
// Метод ниже вернет true, потому что администраторы могут удалять посты
$rbac->isGranted('Administrator', 'post.delete');
Метод isGranted() проверяет роль и ее дочерние роли и ищет заданную привилегию. Если эту привилегию
удается найти, метод возвращает true, иначе – false.