Yii2 RBAC 角色管理(二)

管理平台 > 权限管理 > 角色 role 管理

开发环境:
homestead: Ubuntu + Nginx + PHP7 + Mysql
Yii: yii2-app-advanced

本人使用的是 yii2-app-advanced 版本来进行开发,如果使用 yii2-app-basic,请修改相应的命名空间。
由于本人表单使用原生 html,所以在书写的时候要格外注意 csrf 的设置,不然的话,表单将无法提交成功。

首先关于 RBAC 的使用方式请参考本人另外一篇文章 Yii2 使用 RBAC

创建控制器

建立 RoleController 控制器来管理角色

1
2
3
4
5
6
7
8
9
10
11
12
<?php
namespace backend\controllers;

use Yii;
use yii\db\Query;
use common\models\User;
use yii\web\Controller

class RoleController extends Controller
{

}

角色列表

获取全部角色,展示成列表,调用 vendor/yiisoft/yii2/rbac/BaseManager.php 文件中 getRoles 方法获取

1
2
3
4
5
6
7
# 控制器方法
public function actionIndex()
{
$auth = Yii::$app->getAuthManager();
$data = $auth->getRoles();
return $this->render('index', ['data' => $data]);
}

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
<?php
# 模板 backend/views/role/index.php

use yii\helpers\Url;
$this->params['breadcrumbs'][] = 'Role';
?>

<div class="operate">
<a href="<?= Url::to(['role/create']) ?>" class="btn btn-success">Create Role</a>
</div>

<table class="table table-bordered table-hover">
<thead>
<tr>
<th>Name</th>
<th>Description</th>
<th>Operation</th>
</tr>
</thead>
<tbody>
<?php foreach ($data as $row): ?>
<tr>
<td><?= $row->name; ?></td>
<td><?= $row->description; ?></td>
<td>
<a href="<?= Url::to(['role/update', 'name' => $row->name]) ?>"
class="glyphicon glyphicon-edit" title="edit"></a>&nbsp;&nbsp;
<a href="<?= Url::to(['role/delete', 'name' => $row->name]) ?>"
class="glyphicon glyphicon-trash" title="delete"></a>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>

创建角色

实现表单展示和 POST 方法创建新的角色,首先用 createRole 方法创建一个 Role 对象,再调用 vendor/yiisoft/yii2/rbac/BaseManager.php 文件中 add 方法将角色入库

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public function actionCreate()
{
$request = Yii::$app->getRequest();
if ($request->isPost) {
$auth = Yii::$app->authManager;
$name = $request->post('name', '');
if ($name) {
try {
$role = $auth->createRole($name);
$role->description = $request->post('description', '');
$auth->add($role); // 新增角色方法,此方法和新增权限用的方法一样,主要是传的参数不一样
return $this->redirect(['role/index']);
} catch (\Exception $e) {
$error = $e->getMessage();
}

} else {
$error = '请填写角色名称';
}
}

return $this->render('create', ['error' => $error]);
}

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
<?php
# 模板 backend/views/role/create.php
$this->params['breadcrumbs'][] = [
'label' => 'Role',
'url' => 'role/index'
];
$this->params['breadcrumbs'][] = 'Create Role';
?>

<?php if(!empty($error)): ?>
<div class="alert alert-danger">
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">&times;</button>
<div><?= $error; ?></div>
</div>
<?php endif; ?>

<form action="" method="post">
<table class="table table-bordered table-hover">
<tbody>
<tr>
<th width="15%">Name</th>
<td>
<input type="text" class="form-control" name="name">
</td>
</tr>
<tr>
<th>Description</th>
<td>
<input type="text" class="form-control" name="description">
</td>
</tr>
<tr>
<th></th>
<td>
<input type="hidden" name="_csrf-backend"
value="<?=Yii::$app->getRequest()->getCsrfToken(); ?>">
<input type="submit" class="btn btn-success" value="Create">
</td>
</tr>
</tbody>
</table>
</form>

添加子角色

一个角色下面可以包含多个子角色,一般简单的权限系统不会用到,但是可以了解一下

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
# 控制方法
public function actionChild()
{
$name = Yii::$app->getRequest()->get('name', '');
$auth = Yii::$app->authManager;
$role = $roleList = null;
if ($name) {
$role = $auth->getRole($name);
if (Yii::$app->getRequest()->getIsPost()) {
// 删除全部已有的子角色
$sql = "delete from auth_item_child where parent='{$name}' and child in (select name from auth_item where type=1)";
Yii::$app->db->createCommand($sql)->execute();
// 将新的写入到库中
$child = Yii::$app->getRequest()->post('child', []);
foreach ($child as $key => $value) {
$node = $auth->getRole($value);
$auth->addChild($role, $node);
}
return $this->redirect(['role/index']);
}

$roleList = $auth->getRoles();
$child = $auth->getChildRoles($name);
$child = $child ? array_keys($child) : [];
}
return $this->render('child', ['role' => $role, 'roleList' => $roleList, 'child' => $child]);
}

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
<?php
// 模板文件 backend/views/role/child.php

use yii\helpers\Html;
use yii\helpers\Url;
$this->params['breadcrumbs'][] = [
'label' => 'Role',
'url' => Url::to(['role/index'])
];
$this->params['breadcrumbs'][] = 'Add Child Role';
?>

<form action="" method="post">
<?php foreach ($roleList as $row):
if ($row->name != $role->name):
?>
<div class="checkbox">
<label>
<input type="checkbox" name="child[]"
value="<?= $row->name ?>"
name="users[]"
<?php if (in_array($row->name, $child)) { echo 'checked'; } ?>
><?=Html::encode($row->name); ?>
</label>
</div>
<?php
endif;
endforeach;
?>

<input type="hidden" name="_csrf-backend" value="<?=Yii::$app->getRequest()->getCsrfToken(); ?>">
<button type="submit" class="btn btn-success">Submit</button>
</form>

角色编辑

展示表单和 POST 方式实现角色更新,调用 vendor/yiisoft/yii2/rbac/BaseManager.php 文件中 update 方法更新
从这里看到调用的方法和权限节点更新是一样的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public function actionUpdate()
{
$name = Yii::$app->getRequest()->get('name', '');
$auth = Yii::$app->authManager;
$role = $auth->getRole($name);
$error = '';
if (Yii::$app->getRequest()->getIsPost()) {
$newName = Yii::$app->getRequest()->post('new_name', '');
$role->name = $newName;
$role->description = Yii::$app->getRequest()->post('description', '');
try {
$auth->update($name, $role);
return $this->redirect(['role/index']);
} catch (\Exception $e) {
$error = $e->getMessage();
}
}

return $this->render('update', ['model' => $role, 'error' => $error]);
}

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
<?php
# 模板 backend/views/role/update.php
$this->params['breadcrumbs'][] = [
'label' => 'Role',
'url' => 'role/index'
];
$this->params['breadcrumbs'][] = 'Update Role';
?>
<?php if(!empty($error)): ?>
<div class="alert alert-danger">
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">&times;</button>
<div><?= $error; ?></div>
</div>
<?php endif; ?>
<form action="" method="post">
<table class="table table-bordered table-hover">
<tbody>
<tr>
<th width="15%">Name</th>
<td>
<input type="text" class="form-control" name="new_name" value="<?= $model->name ?>">
</td>
</tr>
<tr>
<th>Description</th>
<td>
<input type="text" class="form-control" name="description" value="<?= $model->description ?>">
</td>
</tr>
<tr>
<th></th>
<td>
<input type="hidden" name="_csrf-backend"
value="<?=Yii::$app->getRequest()->getCsrfToken(); ?>">
<input type="hidden" name="name" value="<?= $model->name; ?>">
<input type="submit" class="btn btn-info" value="Update">
</td>
</tr>
</tbody>
</table>
</form>

角色删除

调用 vendor/yiisoft/yii2/rbac/BaseManager.php 文件中 revoke 方法进行删除

1
2
3
4
5
6
7
8
9
10
public function actionDelete()
{
$name = Yii::$app->getRequest()->get('name', '');
$auth = Yii::$app->authManager;
$role = $auth->getRole($name); // 获取角色
if ($auth->remove($role)) { // 传入角色信息,进行删除操作
return $this->redirect(['role/index']);
}
die('删除失败');
}

这样角色管理就结束了,下一节我将写授权管理。

©版权声明:原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 & 作者信息

End

坚持原创技术分享,您的支持将鼓励我继续创作!
Flyertutor WeChat Pay

WeChat Pay

Flyertutor Alipay

Alipay