При разработке сайтов часто встречается задача по ограничению доступа части пользователей в доступе к различным страницам и целым модулям сайта, например, к личному кабинету пользователя. Для решения этой задачи в Yii2 имеются фильтры контроля доступа (ACF) — простой и гибкий механизм, который крепится к контроллерам и модулям в виде поведения.
[
'class' => AccessControl::class,
'only' => ['secret'],
'rules' => [
[
'allow' => true,
'actions' => ['secret'],
'roles' => ['@'],
],
],
],
];
}
public function actionSecret()
{
return 'Secret page.';
}
}
Код выше блокирует доступ к странице «test/secret» для всех пользователей не прошедших аутентификацию.
[
'class' => AccessControl::class,
'rules' => [
[
'allow' => true,
'roles' => ['@'],
],
],
],
];
}
}
Код выше блокирует доступ ко всему модулю для всех пользователей не прошедших аутентификацию.
Аутентификация — процесс проверки подлинности пользователя. Обычно осуществляется путем поиска в базе данных пары логина и хеша пароля. Документация по аутентификации в Yii2. Пользователи прошедшие аутентификацию обозначаются символом ‘@‘, а не прошедшие (гости) обозначаются символом "?".
Авторизация — процесс проверки прав доступа пользователей к какому-либо функционалу или модулю. Документация по авторизации в Yii2. Если гость (?) попадает на страницу с доступом только для аутентифицированных (@) пользователей, то его автоматически перебросит (редирект) на страницу аутентификации (форму входа).
Класс AccessControl позволяет задавать следующие параметры:
- only — массив идентификаторов действий (action’ов) контроллера, к которым будут применяться правила. Если этот параметр не задан, то правила будут применяться ко всем действиям контроллера.
[
'class' => AccessControl::class,
'only' => ['index', 'login', 'logout', 'products'],
'rules' => [
// Массив правил.
]
]
- denyCallback — функцию обратного вызова (callback) при запрете доступа по одному из правил из массива rules. Эта функция при необходимости может принимать два параметра: $rule и $action.
[
'class' => AccessControl::class,
'denyCallback' => function () {
die('Доступ запрещен!');
},
'rules' => [
// Массив правил.
]
]
- ruleConfig — массив с правилами по умолчанию, можно сказать, что это общие настройки для всех правил из массива rules. Правила доступа из этого массива сливаются с массивом rules и ставятся в начало списка.
'access' => [
'class' => AccessControl::class,
'ruleConfig' => [
'class' => 'yii\filters\AccessRule',
'roles' => ['?'], // Для всех гостей системы.
],
'rules' => [
// Разрешаем доступ к странице "actionIndex".
[
'allow' => true,
'actions' => ['index'],
],
// Запрещаем доступ к странице "actionSecret".
[
'allow' => false,
'actions' => ['secret'],
],
],
],
- rules — массив с правилами доступа к действиям (action’ам). Каждое правило доступа можно назвать объектом (оно в него преобразуется) класса AccessRule, который имеет несколько свойств (публичных полей). Настраивая и комбинируя эти поля можно построить гибкую систему доступа.
Настройки "rules"
- allow — тип правила, true — разрешение, false — запрет.
'access' => [
'class' => AccessControl::class,
'rules' => [
[
'allow' => true,
// Другие параметры.
],
],
],
- actions — массив идентификаторов действий (action’ов).
'access' => [
'class' => AccessControl::class,
'rules' => [
[
'actions' => ['index', 'users', 'products'],
// Другие параметры.
],
],
],
- controllers — массив идентификаторов контроллеров. Обычно применяется при конфигурации модулей. Если свойство не указано, то оно действует на все контроллеры.
'access' => [
'class' => AccessControl::class,
'rules' => [
[
'controllers' => ['site', 'products', 'users'],
// Другие параметры.
],
],
],
- roles — роли пользователя.
'access' => [
'class' => AccessControl::class,
'rules' => [
[
'roles' => ['?'], // Правило для гостей.
// Другие параметры.
],
[
'roles' => ['@'], // Правило для аутентифицированных пользователей.
// Другие параметры.
],
],
],
- ips — массив IP-адресов.
'access' => [
'class' => AccessControl::class,
'rules' => [
[
'ips' => ['127.0.0.1'],
// Другие параметры.
],
],
],
- verbs — HTTP метод (GET, POST, OPTIONS, HEAD, PUT, DELETE, TRACE, CONNECT или PATCH).
'access' => [
'class' => AccessControl::class,
'rules' => [
[
'verbs' => ['GET', 'POST', 'PUT'],
// Другие параметры.
],
],
],
- matchCallback — это функция обратного вызова (callback), которая определяет будет ли применяться правило или нет. Он должна вернуть true (правило сработает) или false (правило будет проигнорировано).
'access' => [
'class' => AccessControl::class,
'rules' => [
[
'matchCallback' => function () {
// Метод isAdministrator() вернет true или false в зависимости от роли пользователя.
return \Yii::$app->user->identity->isAdministrator();
},
// Другие параметры.
],
],
],
- denyCallback — это функция обратного вызова (callback), которая будет вызвана при запрете доступа из текущего правила. Обычно генерируют исключение, переадресуют пользователя на другую страницу или завершают работу скрипта как в примере ниже.
'access' => [
'class' => AccessControl::class,
'rules' => [
[
'denyCallback' => function () {
die('Доступ закрыт!');
}
// Другие параметры.
],
],
],
Через комбинирование свойств классов AccessControl и AccessRule можно выстроить практически любую логику доступа к модулям, контроллерам и их действиям. Для наглядности добавлю еще один пример:
[
'class' => AccessControl::class,
'only' => ['user', 'admin'], // Устанавливаем правила только для site/user и site/admin. К site/index имеют доступ все.
'rules' => [
[
'allow' => true,
'actions' => ['user'],
'roles' => ['@'],
'denyCallback' => function () {
die('Эта страница доступна только аутентифицированным пользователям!');
},
],
[
'allow' => true, // Разрешаем доступ.
'actions' => ['admin'], // К действию site/admin
'roles' => ['@'], // Только аутентифицированному пользователю.
'ips' => ['127.0.0.1'], // С IP-адресом "127.0.0.1".
'verbs' => ['GET', 'POST', 'PUT'], // Через HTTP методы GET, POST и PUT.
'matchCallback' => function () {
// Если пользователь имеет полномочия администратора, то правило доступа сработает.
return Yii::$app->user->identity->role == User::ROLE_ADMIN;
},
'denyCallback' => function () {
// Если пользователь не подпадает под все условия, то завершаем работы и выдаем своё сообщение.
die('Эта страница доступна только администратору!');
},
],
],
],
];
}
public function actionIndex()
{
return 'Страница для всех посетителей сайта.';
}
public function actionUser()
{
return 'Страница только для аутентифицированных посетителей сайта.';
}
public function actionAdmin()
{
return 'Страница только для администратора сайта.';
}
}
Yii2 из коробки предоставляет еще один способ авторизации — на основе ролей (RBAC — role based access control), который является более гибким механизмом, но эта гибкость может привести к излишней сложности кода. Для большинства проектов достаточно использования ACF, даже если в системе присутствуют несколько ролей. Контролировать и совмещать доступ нескольких пользователей с разными ролями можно через matchCallback, например:
[
'class' => AccessControl::class,
'only' => ['common', 'staff', 'admin'],
'rules' => [
[
'allow' => true,
'actions' => ['common'],
'roles' => ['@'],
'denyCallback' => function () {
die('Эта страница для всех аутентифицированных пользователей!');
},
],
[
'allow' => true,
'actions' => ['staff'],
'roles' => ['@'],
'matchCallback' => function () {
return in_array(Yii::$app->user->identity->role, [
User::ROLE_ADMINISTRATOR,
User::ROLE_MANAGER,
]);
},
'denyCallback' => function () {
die('Страница для персонала: модератора и администратора.');
},
],
[
'allow' => true,
'actions' => ['admin'],
'roles' => ['@'],
'matchCallback' => function () {
return Yii::$app->user->identity->role == User::ROLE_ADMINISTRATOR;
},
'denyCallback' => function () {
die('Страница только для администратора.');
},
],
],
],
];
}
public function actionCommon()
{
return 'Страница для всех пользователей.';
}
public function actionStaff()
{
return 'Страница для персонала: модератора и администратора.';
}
public function actionAdmin()
{
return 'Страница только для администратора.';
}
}
Комментарии (0)