用户管理
- 认证
- 前后台认证分离
- 用户管理页面完善
- 授权
授权
授权是指验证用户是否允许做某件事情的设定,YII提供两种授权方法:
- ACF 存取控制过滤器
- RBAC 基于角色的存取控制
ACF存取控制过滤器
ACF是一种通过yii\filters\AccessControl
类来实现的简单授权方法,非常适用于仅需简单存取控制的应用。
实现ACF的方法
public function behaviors()
{
return [
'access'=>[
'class'=>AccessControl::className(),
//权限规则
'rules'=>[
//登录时检测是否为未认证用户
[
'actions'=>['login', 'error'], //动作
'allow'=>true,
'roles'=>['?'] //角色
],
// 退出时检测用户是否为认证用户
[
'actions'=>['logout', 'index'],
'allow'=>true,
'roles'=>['@']
]
]
]
];
}
在控制器中behaviors()
中设定存取的规则,当用户请求一个动作时,ACF会检查存取规则,判断该用户是否被允许执行所请求的动作。
ACF角色类型(roles)
-
?
表示未经认证的访客用户 -
@
表示已认证用户。
ACF存取规则(rules)
- ips 浏览器的IP地址,可使用通配符
*
,为空表示匹配所有IP。 - verbs 匹配请求方式,如GET、POST。
- matchCallback PHP回调,以确定应用该规则。
- denyCallback PHP回调,当规则禁止访问时被访问。
RBAC基于角色存取控制
- 集中式存取控制机制
- 角色是权限的集合
- 角色和权限都实现了树的层次结构
权限检查
- 一个角色可指派给一个或多个用户
- 系统会检查包含该权限的角色是否指派给该用户
规则
- 规则可是一段代码用来与一个角色或权限关联
- 通过规则的执行检查一个用户是否满足角色或权限要求
实现
- 建立授权数据
配置应用组件authManager
为yii\rbac\DbManager
common\config\main.php
'components'=>[
'authManager'=>['class'=>'yii\rbac\DbManager']
]
使用数据迁移创建表
yii migrate --migrationPath=@yii/rbac/migrations
数据迁移后会在数据库中新增四张表
(1)auth_assignment 指派角色给用户
(2)auth_item 角色表 type=1为父 type=2为子
(3)auth_item_child 角色父子树
(4)auth_rule 规则
通过authManager
提供的API创建一个控制台命令,初始化授权数据。
console/controllers/RbacController.php
<?php
namespace console\controllers;
use Yii;
use yii\console\Controller;
class RbacController extends Controller
{
public function actionInit()
{
$auth = Yii::$app->authManager;
//添加权限
$createPost = $auth->createPermission('createPost');
$createPost->description = '创建文章';
$auth->add($createPost);
$updatePost = $auth->createPermission('updatePost');
$updatePost->description = '更新文章';
$auth->add($updatePost);
$deletePost = $auth->createPermission('deletePost');
$deletePost->description = '删除文章';
$auth->add($deletePost);
$approveComment = $auth->createPermission('approveComment');
$approveComment->description = '审核评论';
$auth->add($approveComment);
//添加角色并授权
$postAdmin = $auth->createRole('postAdmin');
$postAdmin->description = '文章管理员';
$auth->add($postAdmin);
$auth->addChild($postAdmin, $createPost);
$auth->addChild($postAdmin, $updatePost);
$auth->addChild($postAdmin, $deletePost);
$postOperator = $auth->createRole('postOperator');
$postOperator->description = '文章操作员';
$auth->add($postOperator);
$auth->addChild($postOperator, $deletePost);
$commentAuditor = $auth->createRole('commentAuditor');
$commentAuditor->description = '评论审核员';
$auth->add($commentAuditor);
$auth->addChild($commentAuditor, $approveComment);
$admin = $auth->createRole('admin');
$admin->description = '系统管理员';
$auth->add($admin);
$auth->addChild($admin, $postAdmin);
$auth->addChild($admin, $postOperator);
$auth->addChild($admin, $commentAuditor);
//为用户指派角色
$auth->assign($admin, 1);
$auth->assign($postAdmin, 2);
$auth->assign($postOperator, 3);
$auth->assign($commentAuditor, 4);
}
}
控制台执行
yii rbac/init
- 执行权限规则
对新增文章进行权限检查
controllers/PostController.php
//引入异常处理类
use yii\web\ForbiddenHttpException;
//创建文章
public function actionCreate()
{
if(!Yii::$app->user->can('createPost')){
throw new ForbiddenHttpException('权限不足,禁止操作!');
}
$model = new Post();
if ($model->load(Yii::$app->request->post()) && $model->save()) {
return $this->redirect(['view', 'id' => $model->id]);
} else {
return $this->render('create', [
'model' => $model,
]);
}
}
yii\web\User::can()
是一种快捷用法,用于对当前登录用户进行权限检查,若要能对任何用户进行权限检查,需调用yii\rbac\ManagerInterface::checkAccess()
来检查权限。
权限设置页面
创建auth_assignment
和auth_item
的公共模型类
账户管理控制器中添加授权操作
backend/Controllers/adminController.php
use backend\models\AuthItem;
use backend\models\AuthAssignment;
public function actionPrivilege($id)
{
//获取所有权限
$allPrivilegesArray = array();
$allPrivileges = AuthItem::find()->select(['name','description'])->where(['type'=>1])->orderBy('description')->all();
foreach($allPrivileges as $item){
$allPrivilegesArray[$item->name] = $item->description;
}
//获取当前用户权限
$AuthAssignmentsArray = array();
$AuthAssignments = AuthAssignment::find()->select(['item_name'])->where(['user_id'=>$id])->all();
foreach($AuthAssignments as $item){
array_push($AuthAssignmentsArray, $item->item_name);
}
//从表单提交的数据来更新auth_assignment表,从而用户的角色发生变化
if(isset($_POST['privs'])){
AuthAssignment::deleteAll('user_id=:id', [':id'=>$id]);
$privs = $_POST['privs'];
for($i=0; $i<count($privs); $i++){
$priv = new AuthAssignment();
$priv->item_name = $privs[$i];
$priv->user_id = $id;
$priv->created_at = time();
$priv->save();
}
return $this->redirect(['index']);
}
//渲染多选按钮
return $this->render('privilege',[
'id'=>$id,
'AuthAssignmentsArray'=>$AuthAssignmentsArray,
'allPrivilegesArray'=>$allPrivilegesArray
]);
}
添加账户管理设置页面
backend/views/privilege.php
<?php
use yii\helpers\Html;
use yii\widgets\ActiveForm;
$this->title = '权限控制';
$this->params['breadcrumbs'][] = ['label' => '权限设置', 'url' => ['index']];
$this->params['breadcrumbs'][] = '更新';
?>
<div class="admin-privilege ">
<h1><?= Html::encode($this->title) ?></h1>
<div class="admin-privilege-form">
<?php $form = ActiveForm::begin(); ?>
<?= Html::checkboxList('privs', $AuthAssignmentsArray, $allPrivilegesArray) ?>
<div class="form-group">
<?= Html::submitButton('更新', ['class' => 'btn btn-success']) ?>
</div>
<?php ActiveForm::end(); ?>
</div>
</div>
前台建立
- 首页
- 文章页
首页
使用前台脚手架 /frontend/web/index.php?r=gii
生成文章CRUD操作。
修改前台默认首页地址
frontend/config/main.php
return [
'defaultRoute'=>'post/index',
'language'=>'zh-CN',
]