[英]yii2 deny user login on backend
我有應用RBAC遷移的yii2高級模板。 我正在嘗試學習RBAC並遵循Docs 2.0 。
我已使用數據庫登錄,但前端和后端都使用任何帳戶登錄。 我已經做了2個RBAC角色(管理員,用戶),但無法理解或找到如何
限制后端登錄非管理員用戶角色。
以下是角色的代碼。 和數據庫條目:
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 admin@gmail.com 20 10 1421197319 1421197319
user user@gmail.com 10 10 1421198124 1421198124
現行規則:
'rules' => [
[
'actions' => ['login', 'error'],
'allow' => true,
],
[
'actions' => ['logout', 'index'],
'allow' => true,
'roles' => ['@'],
],
解決了 - 注意:解決方案不完全是RBAC而是ACF。
經過搜索和咨詢,我找到了這個yii2 viki的解決方案。
我不清楚RBAC行為,因為我認為它不會讓某個角色在某些操作(登錄,提交等)之前執行特定任務。
實際上,RBAC會讓你做任何嘗試,然后檢查是否允許,如果不允許則阻止。
例
在一個房子里有一些庭院銷售,你可以自由地在它的前院漫游。 房門/入口前面沒有任何防護裝置,也沒有鎖定。 你試圖潛入房子,一旦你進入房子,里面有一些保安人員突然阻止你識別自己,他在房屋安全系統中掃描你的信息(數據庫中的權限),但找不到你的權利在家里。 他強迫你出局。 這個警衛是RBAC
我需要一個守衛在前門,除非他們被允許,否則他們不會讓任何人進入。 這將是ACF。
所以,現在我需要一種方法告訴后端系統特定角色不能事先執行特定操作(即拒絕后端的非管理員登錄),這對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
on True允許執行操作,而False拒絕操作。 isAdmin
是一個需要在User
模型中定義的getter函數。
namespace /common/models/User;
const ROLE_ADMIN = 20;
public function getIsAdmin()
{
return $this->role == self::ROLE_ADMIN;
}
我在這個yii2 viki的評論中發布了模型的完整工作代碼。
你們首先登錄用戶然后檢查他的角色,沒有必要。 您的LoginForm模型具有getUser()
方法,在調用load()
和validate()
之后找到它,並使用authManager
檢查角色。 像這樣的Smth:
/** @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
param添加到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,
]);
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.