Эта статья является дополнением и продолжением предыдущей статьи по авторизации в Yii2. В ней мы рассмотрим контроль доступа к модулям, контроллерам, действиям и отдельным функциям на основе встроенного в Yii2 механизма RBAC.

Для начала нужно сказать о самом главном аспекте RBAC — его области применения, в подавляющем большинстве случаев полноценный контроль доступа на основе ролей нужен для систем, в которых администратору придется динамически изменять права у различных групп пользователей через панель администратора или любой другой интерфейс.

Вторым важным аспектом является понимание терминов с которыми работает RBAC:

  • роль (role) — принадлежность пользователя к какой-либо группе, которая определяет его права доступа. Примеры: администратор, модератор, обычный пользователь.
  • разрешение (permission) — возможность доступа к какому-либо функционалу. Примеры: открытие страницы, добавление статьи, редактирование личных данных.
  • правило (rule) — набор требований к пользователю, которым он должен соответствовать для получения доступа к функционалу. Правила могут крепиться как к роли(role), так и к разрешению(permission). Примеры: проверка авторства статьи перед её редактированием, проверка подтверждения контактных данных покупателя в магазине перед оформлением покупки, проверка возраста пользователя перед заказом билета.
  • привязка (assigment) — установка связей между сущностями RBAC. Примеры: привязка роли к пользователю, привязка правила к пользователю.
  • наследование (в Yii2 — addChild()) — передача прав доступа (разрешений и правил). Примеры: наследование роли от роли, роли от разрешения.

Давайте перейдем к обзору реализации RBAC в Yii2, точнее к двум её вариантам: PhpManager и DbManager. Различие между этими двумя реализациями состоит в способе хранения данных, в PHP файлах и базе данных соответственно. К плюсам PhpManager’а можно отнести скорость работы на небольшом количестве пользователей из-за хранения всей инфраструктуры менеджера в файлах, но этот плюс постепенно превращается в минус при росте количества пользователей, так как эти файлы начинают расти в размерах. Сильной стороной  DbManager’а является гибкое управление политикой доступа (для этих задач обычно реализуется раздел в панели администратора) к функционалу и относительно высокая скорость работы при большом количестве пользователей.

В примерах этой статьи используется шаблон приложения basic.

Для подключения RBAC менеджера нужно настроить компонент в двух файлах конфигурации: «../config/web.php» и «../config/console.php».

Для функционирования DbManager’а требуется настроенное подключение к БД и применение миграции от разработчиков фреймворка:

А для работы PhpManager’а необходимо лишь наличие директории @app/rbac/ с правами записи для сервера.

После подключения RBAC-менеджера необходимо создать требуемые роли, разрешения и правила, которые можно будет присоединять к пользователю. Для небольших систем эти операции выводят в отдельный контроллер (RbacController например) или в миграцию, но вы можете делать это там, где заходите, разницы никакой нет. А для больших систем часто пишут свою надстройку для управления правами доступа или используют стороннее расширение наподобие yii2-admin.

РОЛИ

Для примера создадим три роли: администратор, модератор и пользователь.

После выполнения кода выше в таблице auth_item (для DbManager) или в файле app/rbac/items (для PhpManager) должны появиться записи для наших ролей. Эти роли уже можно использовать для контроля доступа. Чтобы протестировать работу нашего менеджера привяжем каждую из ролей к разным пользователям.

В реальных приложениях пользователям присваивают роли при регистрации в системе, здесь же для примера они были добавлены ранее и найдены через findOne() по идентификатору. После выполнения этого кода в таблице auth_assignment (для DbManager) или в файле app/rbac/items (для PhpManager) добавятся записи для связи ролей и пользователей.

Если вы раньше не использовали RBAC менеджер, то скорее всего создавали поле «role» в таблице пользователей и записывали туда присвоенное имя роли. Теперь вся работа с ролями будет происходить через RBAC менеджер и в поле «role» нет надобности.

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

Если вам ранее приходилось использовать фильтры контроля доступа (ACF), то представленный выше способ ограничения доступа покажется знакомым за одним исключением — появилась возможность указывать свои роли в параметре «roles» вместо двух стандартных @ и ?.

РАЗРЕШЕНИЯ

Разрешения позволят нам более гибко управлять доступом. Продолжим развивать предыдущий пример: создадим разрешение на доступ к странице управления пользователями (SiteController/ManageArticles) и добавим его к роли модератора, что бы Петров тоже мог видеть всех пользователей:

После создания и привязки разрешения мы можем начать с ней работать. Есть два варианта: через ACF и через метод «can()» в компоненте «User».

Через ACF:

Через метод «can()» в компоненте «User»:

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

ПРАВИЛА

Правила в RBAC являются «вишенкой на торте» в управлении доступом, так как они позволяют еще точнее задать условия доступа для каждой роли и даже для отдельного пользователя. Еще больше разовьем наш пример и задействуем последнего пользователя — Сидорова, который пока не принимал участия в работе на системой. Дадим возможность редактировать свои статьи всем пользователям.

Для начала создадим само правило проверки авторства статьи:

Теперь добавим это правило в систему и прикрепим к роли пользователя:

Осталось опробовать наше правило:

На этом описание работы встроенного в Yii2 RBAC менеджера закончено. Если вам показалось, что в управлении доступом на основе ролей трудно разобраться, то это только первое впечатление, оно когда-то было и у меня. После пары часов практики все должно проясниться, главное начать пробовать.

Добавить комментарий