场景
有时候一个小项目,想实管理员才能登录后台,其实没必要引入复杂的 RBAC,可以利用 Yii User 表里面的 role
字段来实现这个效果。
实战:后台只有管理员才能登录
第一步:修改 common\models\User
文件,添加如下静态常量:
const ROLE_USER = 10;
const ROLE_ADMIN = 20;
第二步:修改 common\models\User
文件,修改 rules
规则:
['role', 'default', 'value' => 10],
['role', 'in', 'range' => [self::ROLE_USER, self::ROLE_ADMIN]],
第三步:修改 common\models\User
文件,添加判断是否是超级管理员的 isUserAdmin
静态方法:
/**
* @param $username
* @return bool
*/
public static function isUserAdmin($username)
{
if (static::findOne(['username' => $username, 'role' => self::ROLE_ADMIN])) {
return true;
} else {
return false;
}
}
第四步:修改 common\models\LoginForm
文件,添加 loginAdmin
方法:
/**
* @return bool
*/
public function loginAdmin()
{
if ($this->validate()) {
if (User::isUserAdmin($this->username)) {
return Yii::$app->user->login($this->getUser(), $this->rememberMe ? 3600 * 24 * 30 : 0);
}
$this->addError('username', 'You don\'t have permission to login.');
} else {
$this->addError('password', Yii::t('app', 'Incorrect username or password.'));
}
return false;
}
第五步:修改 backend\controllers\SiteController.php
, 修改 actionLogin
方法:
把 $model->login()
改成 $model->loginAdmin()
。
public function actionLogin()
{
if (!\Yii::$app->user->isGuest) {
return $this->goHome();
}
$model = new LoginForm();
if ($model->load(Yii::$app->request->post()) && $model->loginAdmin()) {
return $this->goBack();
} else {
return $this->render('login', [
'model' => $model,
]);
}
}
第六步:未登录用户只能访问登录页面
实现方式一:新建 backend\controllers\Controller.php
文件,代码如下:
除了 SiteController
其他控制器都要继承此控制器,方可实现我们最终效果,切换其他控制器要使用 behaviors
的时候记得要 ArrayHelper::merge
父类 behaviors
。
<?php
/**
* author : forecho <caizh@chexiu.cn>
* createTime : 2016/3/10 14:39
* description:
*/
namespace backend\controllers;
use yii\filters\AccessControl;
class Controller extends \yii\web\Controller
{
public function behaviors()
{
return [
// 后台必须登录才能使用
'access' => [
'class' => AccessControl::className(),
'rules' => [
[
'allow' => true,
'roles' => ['@'],
],
],
],
];
}
}
实现方式二:新建 common\components\AccessControl.php
文件,代码如下:
<?php
/**
* author : forecho <caizhenghai@gmail.com>
* createTime : 16/8/14 下午10:38
* description:
*/
namespace common\components;
use Yii;
use yii\web\User;
use yii\di\Instance;
class AccessControl extends \yii\base\ActionFilter
{
/**
* @var User User for check access.
*/
private $_user = 'user';
/**
* Get user
* @return User
*/
public function getUser()
{
if (!$this->_user instanceof User) {
$this->_user = Instance::ensure($this->_user, User::className());
}
return $this->_user;
}
/**
* Set user
* @param User|string $user
*/
public function setUser($user)
{
$this->_user = $user;
}
/**
* @inheritdoc
*/
public function beforeAction($action)
{
$user = $this->getUser();
return $this->denyAccess($user);
}
/**
* @param User|string $user
* @return bool
*/
protected function denyAccess($user)
{
if ($user->getIsGuest()) {
$user->loginRequired();
}
return true;
}
/**
* @param \yii\base\Action $action
* @return bool
*/
protected function isActive($action)
{
$uniqueId = $action->getUniqueId();
if ($uniqueId === Yii::$app->getErrorHandler()->errorAction) {
return false;
}
$user = $this->getUser();
if ($user->getIsGuest() && is_array($user->loginUrl) && isset($user->loginUrl[0]) && $uniqueId === trim($user->loginUrl[0], '/')) {
return false;
}
return true;
}
}
修改 `` 配置文件,添加代码:
'as access' => [
'class' => 'common\components\AccessControl',
],
'components' => [
// ···
],
本文由 forecho 创作,出自https://getyii.com/topic/585。