本文實例講述了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