yii2项目实战-通过行为,解决rbac的分配问题

今天我们就准备结束漫长的RBAC啦,当然,看完我们今天讲的内容,你应该能够独立的实现一套RBAC管理体系了!为什么这么说呢,因为即使我们后面引入一套第三方的rbac组件,还是有很多人不喜欢他的风格,想要定制呢!

好啦,我们言归正传,看看如何通过行为解决困扰我们几节课的矛盾吧。

等等,等等,有同学上来要问了,我们在基于角色的访问控制(rbac)分配案例文末抛出的100个控制器的问题,当时说要通过行为解决的,可是上节课讲的行为听是听懂了,但是还是没解决这个100个控制器的问题呀,不还是需要手动一个一个的去附加行为吗?

容我想想,还真是这么回事。不过,我上节课说行为还有其他的附加形式,不知道你私下有没有翻翻手册呢?

还不知道怎么处理的,我提个醒,通过配置去附加行为。在你的配置文件main.php中,components同级添加如下代码,注意位置千万不要写错了。

1
'as myBehavior2' => MyBehavior::className(),

然后自己去尝试下效果吧,我们继续讲本篇的重点。

目前我们的 BlogController 有5个操作,分别是index、view、create、update 和 delete,我们来看看如何判断用户是否有操作这几个action的权限!

打开 RbacController,我们先把这几个路由权限添加并分配给“博客管理”这个角色。(上上篇文章中我们已经把该角色分配给uid=1的用户了哦~)

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
<?php
namespace backend\controllers;

use Yii;
use yii\web\Controller;

class RbacController extends Controller
{
// 添加权限
public function actionInit2 ()
{
$auth = Yii::$app->authManager;

// 添加权限, 注意斜杠不要反了
$blogView = $auth->createPermission('/blog/view');
$auth->add($blogView);
$blogCreate = $auth->createPermission('/blog/create');
$auth->add($blogCreate);
$blogUpdate = $auth->createPermission('/blog/update');
$auth->add($blogUpdate);
$blogDelete = $auth->createPermission('/blog/delete');
$auth->add($blogDelete);

// 分配给我们已经添加过的"博客管理"权限
$blogManage = $auth->getRole('博客管理');
$auth->addChild($blogManage, $blogView);
$auth->addChild($blogManage, $blogCreate);
$auth->addChild($blogManage, $blogUpdate);
$auth->addChild($blogManage, $blogDelete);
}
}

接着访问 /index.php?r=rbac/init2 来执行我们刚刚写好的程序。空白…空白就对了,执行结束就意外着这几个权限我们已经添加成功了!

下面,就是我们重点要实现的验证授权啦!

在 backend\components 中创建行为类 AccessControl,

修改 BlogController 的 behaviors 方法,配置一下我们的行为类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/**
* @inheritdoc
*/
public function behaviors()
{
return [
//附加行为
// 'myBehavior' => \backend\components\MyBehavior::className(),
'as access' => [
'class' => 'backend\components\AccessControl',
],
'verbs' => [
'class' => VerbFilter::className(),
'actions' => [
'delete' => ['POST'],
],
],
];
}

注:这里写的 ‘as access’ 只是一个名字而已,没什么其他的含义。

就像我们开篇所说的100个控制器的问题,你就不用再每一个控制器都附加行为啦,通过配置,一键解决所有问题。

好了,下面我们就简单的看一下这个授权行为类的实现吧。

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
<?php
namespace backend\components;

use Yii;
use yii\web\ForbiddenHttpException;

class AccessControl extends \yii\base\ActionFilter
{
/**
* 对用户请求的路由进行验证
* @return true 表示有权访问
*/
public function beforeAction ($action)
{
// 当前路由
$actionId = $action->getUniqueId();
$actionId = '/' . $actionId;

// 当前登录用户的id
$user = Yii::$app->getUser();
$userId = $user->id;

// 获取当前用户已经分配过的路由权限
// 写的比较简单,有过基础的可自行完善,比如解决"*"的问题,看不懂的该行注释自行忽略
$routes = [];
$manager = Yii::$app->getAuthManager();
foreach ($manager->getPermissionsByUser($userId) as $name => $value) {
if ($name[0] === '/') {
$routes[] = $name;
}
}

// 判断当前用户是否有权限访问正在请求的路由
if (in_array($actionId, $routes)) {
return true;
}

$this->denyAccess($user);
}

/**
* 拒绝用户访问
* 访客,跳转去登录;已登录,抛出403
* @param $user 当前用户
* @throws ForbiddenHttpException 如果用户已经登录,抛出403.
*/
protected function denyAccess($user)
{
if ($user->getIsGuest()) {
$user->loginRequired();
} else {
throw new ForbiddenHttpException('不允许访问.');
}
}
}

rbac系列的文章我们到这里就讲解了5篇从基础到高级的文章,从数据表到实现方式基本上是里里外外讲个了通透!我们的目的非常简单,重难点让你更轻易的理解!

但是,操作中不知道你有没有发现,每次我们添加权限都是要通过 rbacController 进行操作,这明显又是一个麻烦的事情!从另一个层面去说,完全没关系,我们只要实现界面化是不是就ok了呢?是的,完全就是这么回事!如果你有定制开发rbac的需求,剩下的界面化工作就交给你啦。

对绝大多数人来说,理解原理才是最重要的。万一真有哪一天要自己实现一套权限控制体系,那也都不是事。

后面,我们就不带大家手动开发界面上的操作部分啦,我们准备集成组件 yii2-admin,来快速完善我们的管理平台!

当然,到后面你会发现,yii2-admin这套组件,完全就是按照我们这几篇文章讲的一样,不过是比我们完善了界面上的操作。