У меня есть шаблон продвижения yii2 с примененной миграцией RBAC. Я пытался выучить RBAC и следовал Документы 2.0.
Я вошел в систему с использованием базы данных, но интерфейс и бэкэнд входят в систему с любой учетной записью. Я сделал 2 роли RBAC (администратор, пользователь), но не могу понять или найти, как
ограничить back-end для входа в систему не-администраторской роли пользователя.
Ниже приведен код для ролей. и записи базы данных:
namespace console\controllers;
use Yii;
use yii\console\Controller;
class RbacController extends Controller
{
public function actionInit()
{
$auth = Yii::$app->authManager;
// add "admin" role
$admin = $auth->createRole('admin');
$auth->add($admin);
// add "user" role
$user = $auth->createRole('user');
$auth->add($user);
$auth->assign($admin, 1);
}
}
Таблица пользователей:
admin [email protected] 20 10 1421197319 1421197319
user [email protected] 10 10 1421198124 1421198124
Действующие правила:
'rules' => [
[
'actions' => ['login', 'error'],
'allow' => true,
],
[
'actions' => ['logout', 'index'],
'allow' => true,
'roles' => ['@'],
],
Решено — Примечание. Решение — не точно RBAC, а ACF.
После поиска и консультации я нашел решение на Это yii2
Viki.
Я не был уверен в поведении RBAC, потому что думал, что это не позволит
выполнить определенное задание перед каким-либо действием (войти, отправить и т. д.).
На самом деле, RBAC позволит вам делать все, что вы пытаетесь, а затем проверяет
за разрешение и заблокировать, если не разрешено.
пример
В доме есть распродажа, и вы можете свободно бродить
вокруг переднего двора. Ворота / подъезд дома не имеют охраны
спереди и не заблокирован. Вы пытаетесь проникнуть в дом и как
Вскоре вы попадаете в дом, там есть охранник, который
резко останавливает вас, чтобы идентифицировать себя, он сканирует вашу информацию в
система безопасности дома (разрешения в БД) и не находит ваш
право быть в доме. Он вытесняет тебя. Этот охранник является RBACМне понадобился охранник у ворот, который никого не впустит, если
им разрешено. И это будет АКФ.Итак, теперь мне нужен был способ сказать внутренней системе, что конкретный
роль не может выполнить определенное действие заранее (то есть запретить не-администратору
войдите на сервер), с RBAC это невозможно, поэтому мы
может использовать ‘matchCallback’, используя ACF.
Правила бэкэнда:
'rules' => [
[
'actions' => ['login'],
'allow' => true,
],
[
'actions' => ['logout', 'index'],
'allow' => true,
'roles' => ['@'],
'matchCallback' => function ($rule, $action) {
return Yii::$app->user->identity->isAdmin;
}
],
]
matchCallback
Значение True разрешает выполнение действий, а значение False запрещает действие. isAdmin
это функция получения, которая должна быть определена в User
модель.
namespace /common/models/User;
const ROLE_ADMIN = 20;
public function getIsAdmin()
{
return $this->role == self::ROLE_ADMIN;
}
Я разместил полный рабочий код модели в Это yii2 Вики комментарии.
Вы оба сначала авторизуетесь, а потом проверяете его роль, в этом нет необходимости.
Ваша модель LoginForm имеет getUser()
метод, найдите его после вызова load()
а также validate()
и проверьте роль с authManager
, Что-то вроде этого:
/** @var LoginForm $model */
$model = Yii::createObject('loginForm');
if ($model->load(Yii::$app->request->post()) && $model->validate()) {
/** @var User $user */
$user = $model->getUser();
if (!empty($user) && Yii::$app->authManager->checkAccess($user->getId(), 'admin')) {
// Don't validate twice
$model->login(false);
return $this->goBack();
} else {
$model->addError('email', 'This user is not authorized for administration');
}
}
return $this->render('login.twig', [
'model' => $model,
]);
Вы также не хотите validate()
LoginForm дважды, так что добавьте $runValidation
парам к login()
метод.
public function login($runValidation = true)
{
if ($runValidation) {
Вы должны добавить поведение к своему контроллеру, например так:
public function behaviors()
{
return [
'access' => [
'class' => AccessControl::className(),
'rules' => [
[
'actions' => ['create', 'delete', 'update'],
'allow' => true,
'roles' => ['admin'],
],
[
'actions' => ['index', 'view'],
'allow' => true,
'roles' => ['user'],
],
],
],
];
}
или это РЕДАКТИРОВАТЬ: (правило так, что любой может получить доступ к входу в систему, но только администратор может войти в систему и получить доступ к странице индекса):
public function behaviors()
{
return [
'access' => [
'class' => AccessControl::className(),
'rules' => [
[
'actions' => ['login'],
'allow' => true,
'roles' => ['?'],
],
[
'actions' => ['index'],
'allow' => true,
'roles' => ['admin'],
],
],
],
];
}
Я достиг этой функциональности, изменив действие входа в систему.
вот мой код, я не знаю, это идеальное решение или нет, но он работает для меня.
public function actionLogin()
{
if (!\Yii::$app->user->isGuest) {
return $this->goHome();
}
$model = new LoginForm();
if ($model->load(Yii::$app->request->post()) && $model->login()) {
//check user roles, is user is Admin?
if (\Yii::$app->user->can('Admin'))
{
// yes he is Admin, so redirect page
return $this->goBack();
}
else // if he is not an Admin then what :P
{ // put him out :P Automatically logout.
Yii::$app->user->logout();
// set error on login page.
\Yii::$app->getSession()->setFlash('error', 'You are not authorized to login Admin\'s penal.<br /> Please use valid Username & Password.<br />Please contact Administrator for details.');
//redirect again page to login form.
return $this->redirect(['site/login']);
}
} else {
return $this->render('login', [
'model' => $model,
]);
}
}