До сих пор я разрабатывал веб-приложения с использованием Yii 1.1.14, но теперь пришло время для обновления.
Компания, в которой я работаю, разработала свою собственную систему контроля доступа, и я был в порядке с ней, пока не увидел, что это на самом деле … Комбинация из 8 таблиц в базе данных (не считая таблицы пользователей) с кучей иностранных ключей.
Это работает хорошо, но, с моей точки зрения, на поддержание всех этих таблиц уходит очень много времени, и в какой-то момент, когда ваше приложение выходит в сеть, если оно затрагивает определенное количество пользователей, оно может стать очень медленным. особенно потому, что 2 из этих таблиц имеют первичный ключ таблицы пользователя в качестве внешнего ключа.
Поэтому я решил, что когда я начну разрабатывать на Yii 2, я начну использовать RBAC, поэтому я начал искать учебники в Интернете … Я только нахожу много разных версий одного и того же кода с ролью автора и разрешениями для создавать или обновлять сообщения.
Я нашел комбинацию из 5 видео на Youtube, но они о Yii 1 RBAC. Они были полезны, потому что мне удалось понять большую часть функциональности RBAC, но у меня все еще есть некоторые сомнения, что я буду
перечислим ниже. И имейте в виду, что для этой системы контроля доступа я использую DBManager учебный класс.
Мои сомнения
РБАК в Yii 1 имел 3 таблицы: auth_assignment
, auth_item
а также auth_item_child
, Теперь в Yii 2 RBAC появляется новая таблица, которая называется auth_rule
и я до сих пор не понимаю, что там делает эта конкретная таблица, как ее использовать или как ее заполнить.
Я вижу, что можно ограничить доступ пользователя к некоторым действиям, используя метод поведения контроллера и назначая доступ к некоторым действиям в зависимости от роли пользователя, но когда дело доходит до этого, я должен разделить свой вопрос на 2:
2.1. Первый: Если вы можете просто ограничить доступ к действиям, настроив его в методе поведения, то зачем использовать сохранение разрешений для auth_item
Таблица?
2.2. Во-вторых: Если вы решили управлять доступом в соответствии с разрешениями, то как именно вы это делаете, потому что я пишу код следующего типа внутри каждой функции и не думаю, что использование RBAC должно быть утомительным. Должен быть другой путь.
public function actionView($id)
{
if(Yii::$app->user->can('view-users')){
return $this->render('view', [
'model' => $this->findModel($id),
]);
}else{
#Redirect to a custom made action that will show a view
#with a custom error message
$this->redirect(['//site/notauthorized']);
}
}
Из-за системы контроля доступа, которую мы используем прямо сейчас, когда пользователь входит в систему, выполняется сложный запрос, который в конечном итоге возвращает массив, который будет сохранен как переменная сеанса, и будет использоваться для создания меню с таким количеством выпадающие списки как категории меню, к которым принадлежат контроллеры, к которым у пользователя есть доступ. Как это можно сделать с помощью RBAC?
Я действительно могу ответить только на 2.2 вашего вопроса, так как 3 совсем не похоже на то, что должен делать RBAC. Однако вы можете получить необходимую информацию из таблицы правил, скорее всего, при условии соблюдения соглашения об именах, соответствующего вашим контроллерам или действиям.
На вопрос 2.2, хотя:
Вы можете просто установить поведение следующим образом:
public function behaviors()
{
return [
'access' => [
'class' => AccessControl::className(),
'rules' => [
[
'allow' => true,
'actions' => ['view'],
'roles' => ['view-users'], //<-- Note, rule instead of role
],
]
]
}
Это не решает другую проблему разрешений в стиле ‘view-own-users’, так как для этого требуется проверить модель ActiveRecord (ну, по крайней мере, в моем приложении). Если Вы хотите добиться этого, посмотрите мой пост на форумах Yii здесь:
Я использую это в одном из самых простых методов, я использую их в поведении моего контроллера.
public function behaviors()
{
return [
'access' => [
'class' => \yii\filters\AccessControl::className(),
'rules' => [
[
'allow' => true,
'roles' => ['sysadmin'],
'actions' => ['index','view','update'],
],
[
'allow' => true,
'roles' => ['staff'],
'actions' => ['index','create','update','view'],
],
],
],
];
}
Здесь роли — это роли, созданные в таблице элементов аутентификации в базе данных, и они были назначены пользователям в таблице назначений аутентификации. В поведении мы просто используем его, как указано выше. В приведенном выше коде sysadmin может иметь доступ к индексу, просматривать и обновлять действие, тогда как сотрудники могут иметь доступ к индексу, создавать, обновлять и просматривать действие.
Yii2 нужно немного настроить, когда дело доходит до использования RBAC под вашими контроллерами AccessControl. Я справился с этим, сделав свой собственный файл AccessRule.
namespace app\components;
use Yii;
class AccessRule extends \yii\filters\AccessRule
{
protected function matchRole($user)
{
if (empty($this->roles)) {
return true;
}
foreach ($this->roles as $role) {
if(Yii::$app->authManager->checkAccess($user->identity->code, $role))
return true;
}
return false;
}
тогда в вашем контроллере вы можете использовать что-то вроде этого:
public function behaviors()
{
return [
'access' => [
'class' => AccessControl::className(),
'ruleConfig' => [
'class' => 'app\components\AccessRule'
],
'rules' => [
[
'actions' => ['index', 'resource-type'],
'allow'=> true,
'roles' => ['admin'],
],
],
],
];
}
Где admin определяется как auth_item, а пользователь — в auth_item_assignments.
Как я создал новую систему Rbac для yii2. вы можете получить прямое разрешение на действие, и действие покажет, что вы не авторизованы для этого действия.
Этим вы обнаружите, что вы будете предоставлять доступ только для действий, которые необходимо идентифицировать.
Я загрузил мою деталь здесь вы можете найти много решений Вот.
Это лучшее решение, которое я мог бы предложить при необходимости фильтровать доступ по разрешениям, это утомительно, но может быть полезно, если вы пытаетесь создать роли в продуктивной среде и хотите использовать rbac.
use yii\web\ForbiddenHttpException;if(Yii::$app->user->can('view-users')){
return $this->render('view', [
'model' => $this->findModel($id),
]);
}else{
throw new ForbiddenHttpException('You dont have access to this site');
}