本文实例讲述了YII2框架中使用RBAC对模块,控制器,方法的权限控制及规则的使用。分享给大家供大家参考,具体如下:
在使用YII2中自带的RBAC时,需要先配置config/web.php:
1
2
3
4
5
6
7
8
9
|
return [
// ...
'components' => [
'authManager' => [
'class' => 'yii\rbac\DbManager' ,
],
// ...
],
];
|
如果你需要运行yii migrate来创建表,那么config/console.php也需要同上面一样配置一下。
cmd进入项目目录,运行如下命令:
1
|
yii migrate --migrationPath=@yii/rbac/migrations
|
你会发现在数据库中创建了四张表
1
2
3
4
|
auth_assignment 角色与用户的关联表
auth_item 存放角色与权限,通过type字段区分
auth_item_child 存放角色与权限的上下级关系
auth_rule 规则表,用于扩展权限功能
|
为了演示,我们在控制器下分别写四个方法,分别用来创建权限,创建角色,指派角色,使用规则。
IndexController.php代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
|
<?php
namespace app\controllers;
use YII;
use app\models\MyUserLogin;
use app\rbac\UserUpdSelfRule;
use app\controllers\BaseController;
class IndexController extends BaseController
{
//首页
public function actionIndex()
{
$this ->renderPartial( 'index' );
}
//登陆
public function actionLogin()
{
if (YII:: $app ->request->isPost) {
$user = new MyUserLogin();
$user ->load(YII:: $app ->request->post(), '' );
if ( $user ->login()) {
echo '登陆成功' ;
} else {
echo '登陆失败' ;
}
} else {
return $this ->renderPartial( 'login' );
}
}
//为了演示,这里我们添加几条权限
public function actionPer()
{
$auth = YII:: $app ->authManager;
//创建用户删除权限
$per = $auth ->createPermission( 'user/del' );
$per ->description = '删除用户' ;
$auth ->add( $per );
//创建用户更新权限
$per = $auth ->createPermission( 'user/upd' );
$per ->description = '更新用户' ;
$auth ->add( $per );
//创建用户添加权限
$per = $auth ->createPermission( 'user/add' );
$per ->description = '添加用户' ;
$auth ->add( $per );
//创建用户查看权限
$per = $auth ->createPermission( 'user/list' );
$per ->description = '查看用户列表' ;
$auth ->add( $per );
}
//添加角色
public function actionRole()
{
$auth = YII:: $app ->authManager;
//添加管理员角色
$admin = $auth ->createRole( 'admin' );
$admin ->description = '管理员' ;
$auth ->add( $admin );
//给管理员赋予权限
$auth ->addChild( $admin , $auth ->getPermission( 'user/del' ));
$auth ->addChild( $admin , $auth ->getPermission( 'user/upd' ));
$auth ->addChild( $admin , $auth ->getPermission( 'user/add' ));
$auth ->addChild( $admin , $auth ->getPermission( 'user/list' ));
//添加普通员工角色
$employee = $auth ->createRole( 'employee' );
$employee ->description = '普通员工' ;
$auth ->add( $employee );
$auth ->addChild( $employee , $auth ->getPermission( 'user/list' ));
$auth ->addChild( $employee , $auth ->getPermission( 'user/add' ));
}
//给用户指派角色
public function actionAssign()
{
$auth = YII:: $app ->authManager;
//注意这里的2是用户的ID,即你用户表user里的ID
//也可通过YII::$app->user->id获取
$auth ->assign( $auth ->getRole( 'admin' ), 1);
$auth ->assign( $auth ->getRole( 'employee' ), 2);
}
//添加规则
public function actionRule()
{
$auth = YII:: $app ->authManager;
$rule = new UserUpdSelfRule();
$auth ->add( $rule );
//创建权限,与规则关联
$per = $auth ->createPermission( 'user/upd/updSelf' );
$per ->description = '用户只能修改自已' ;
$per ->ruleName = $rule ->name;
$auth ->add( $per );
//这里,要注意,要把user/upd/updSelf权限设为user/upd的父级
//要不然,普通员工访问user/upd这个方法会被拦住
$auth ->addChild( $per , $auth ->getPermission( 'user/upd' ));
//给普通员工赋予user/upd/updSelf权限,注意我们这里并没有给员工赋予user/upd权限
$auth ->addChild( $auth ->getRole( 'employee' ), $per );
}
}
|
我们在项目目录下创建rbac目录,并创建UserUpdSelfRule.php,来实现用户只能修改自已信息的规则。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
<?php
//注意命名空间要跟你的目录对应
namespace app\rbac;
use yii\rbac\Rule;
//必须继承自yii\rbac\Rule
class UserUpdSelfRule extends Rule
{
public $name = 'userUpdSelf' ;
//必须要实现execute方法
//$user表示用户ID
//$item规则相关的角色或者权限
//$params传递过来的参数
public function execute( $user , $item , $params )
{
//如果没有设置参数ID,直接返回true
if (!isset( $params [ 'id' ])) {
return true;
}
//判断id是否是当前用户ID
return ( $params [ 'id' ] == $user ) ? true : false;
}
}
|
我们访问index/per查看数据表中的变化。
访问index/role结果如下:
访问index/assign结果如下:
访问index/rule结果如下:
为了能够对我们的模块,控制器,方法进行权限控制,我们需要创建一个基类来统一处理,上面的控制器就是继承自基类。
BaseController.php代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
|
<?php
namespace app\controllers;
use YII;
use yii\web\Controller;
class BaseController extends Controller
{
//不需要验证的
protected $noCheckAccess = [
'index/index' ,
'index/per' ,
'index/role' ,
'index/assign' ,
'index/rule' ,
'index/login' ,
];
//不需要登陆的
protected $noLogin = [
'index/login' ,
];
//验证权限
//注意,不要把获取模块名,控制器名,方法名写到init()函数里,那样是获取不到的
//这个坑我已经踩了,大家就不用再去踩了
public function beforeAction( $action )
{
$mid = ! empty ( $this ->module->id) ? $this ->module->id : '' ;
$cid = ! empty ( $this ->id) ? $this ->id : '' ;
$aid = ! empty ( $action ->id) ? $action ->id : '' ;
//如果模块为basic,我们只验证控制器/方法
if ( $mid == 'basic' ) {
$per = "{$cid}/{$aid}" ;
} else {
$per = "{$mid}/{$cid}/{$aid}" ;
}
if (!in_array( $per , $this ->noLogin)) {
if (! $this ->checkOnline()) {
$this ->redirect( 'index/login' );
}
}
if (!in_array( $per , $this ->noCheckAccess)) {
if (!YII:: $app ->user->can( $per )) {
die ( '你没有权限' );
}
}
return parent::beforeAction( $action );
}
//检查是否在线
public function checkOnline()
{
return ! empty (YII:: $app ->user->id) ? true : false;
}
}
|
为了演示,我们创建一个UserController.php,代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
|
<?php
namespace app\controllers;
use YII;
use app\controllers\BaseController;
class UserController extends BaseController
{
public function actionUpd()
{
$id = YII:: $app ->request->get( 'id' , 0);
echo 'user id : ' , YII:: $app ->user->id, '<br>' ;
//先判断用户有没有只能修改自已的权限
if (YII:: $app ->user->can( 'user/upd/updSelf' )) {
//然后再判断修改ID是否与自已的ID一样,在UserUpdSelfRule里进行判断
if (YII:: $app ->user->can( 'user/upd/updSelf' , [ 'id' => $id ])) {
echo '有权修改自已' ;
} else {
echo '不能修改除自已以外的' ;
}
} else {
echo '修改所有' ;
}
}
public function actionDel()
{
echo 'user id : ' , YII:: $app ->user->id, '<br>' ;
echo 'user del' ;
}
public function actionList()
{
echo 'user id : ' , YII:: $app ->user->id, '<br>' ;
echo 'user list' ;
}
public function actionAdd()
{
echo 'user id : ' , YII:: $app ->user->id, '<br>' ;
echo 'user add' ;
}
}
|
我的用户表里有两个用户
分别登陆这两个用户,然后让他们访问user/add,user/del,user/list,user/upd,结果如下:
admin用户状态如下:
test用户状态如下:
test之所以能够访问user/upd是因为我们把user/upd/updSelf设为了user/upd的父级,如果没有设置,这里是会被拦住的。
希望本文所述对大家基于Yii框架的PHP程序设计有所帮助。
原文链接:https://www.cnblogs.com/jkko123/p/8677551.html