服务器之家

服务器之家 > 正文

YII2框架中使用RBAC对模块,控制器,方法的权限控制及规则的使用示例

时间:2020-06-07 14:43     来源/作者:怀素真

本文实例讲述了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查看数据表中的变化。

YII2框架中使用RBAC对模块,控制器,方法的权限控制及规则的使用示例

访问index/role结果如下:

YII2框架中使用RBAC对模块,控制器,方法的权限控制及规则的使用示例

访问index/assign结果如下:

YII2框架中使用RBAC对模块,控制器,方法的权限控制及规则的使用示例

访问index/rule结果如下:

YII2框架中使用RBAC对模块,控制器,方法的权限控制及规则的使用示例

为了能够对我们的模块,控制器,方法进行权限控制,我们需要创建一个基类来统一处理,上面的控制器就是继承自基类。

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';
  }
}

我的用户表里有两个用户

YII2框架中使用RBAC对模块,控制器,方法的权限控制及规则的使用示例

分别登陆这两个用户,然后让他们访问user/add,user/del,user/list,user/upd,结果如下:

admin用户状态如下:

YII2框架中使用RBAC对模块,控制器,方法的权限控制及规则的使用示例

test用户状态如下:

YII2框架中使用RBAC对模块,控制器,方法的权限控制及规则的使用示例

test之所以能够访问user/upd是因为我们把user/upd/updSelf设为了user/upd的父级,如果没有设置,这里是会被拦住的。

希望本文所述对大家基于Yii框架的PHP程序设计有所帮助。

原文链接:https://www.cnblogs.com/jkko123/p/8677551.html

相关文章

热门资讯

歪歪漫画vip账号共享2020_yy漫画免费账号密码共享
歪歪漫画vip账号共享2020_yy漫画免费账号密码共享 2020-04-07
2020微信伤感网名听哭了 让对方看到心疼的伤感网名大全
2020微信伤感网名听哭了 让对方看到心疼的伤感网名大全 2019-12-26
沙雕群名称大全2019精选 今年最火的微信群名沙雕有创意
沙雕群名称大全2019精选 今年最火的微信群名沙雕有创意 2019-07-07
玄元剑仙肉身有什么用 玄元剑仙肉身境界等级划分
玄元剑仙肉身有什么用 玄元剑仙肉身境界等级划分 2019-06-21
男生常说24816是什么意思?女生说13579是什么意思?
男生常说24816是什么意思?女生说13579是什么意思? 2019-09-17
返回顶部