在这个示例中,我们将根据RBAC创建一个从头创建用户权限管理系统。我们将在basic/controller/ AuthorizationManagerController创建一个名为AuthorizationManagerController的控制器。php将显示数据库的权限和角色表中所有可用的权限和角色。此示例基于用户数据表已存在之前的章节。
让我们在此看看这张数据表的结构:
CREATE TABLE `user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`auth_key` varchar(32) COLLATE utf8_unicode_ci NOT NULL,
`password_hash` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`access_token` varchar(100) COLLATE utf8_unicode_ci DEFAULT NULL,
PRIMARY KEY (`id`)
)
我们将重构这张数据表并插入5条数据,用于这一个例子。
TRUNCATE user;
INSERT INTO `user` (`id`, `username`, `auth_key`, `password_hash`, `access_token`)
VALUES
(1, 'foo', '', '$2a$12$hL0rmIMjxhLqI.xr7jD1FugNWEgZNh62HuJj5.y34XBUfBWB4cppW', NULL),
(2, 'userA', '', '$2a$12$hL0rmIMjxhLqI.xr7jD1FugNWEgZNh62HuJj5.y34XBUfBWB4cppW', NULL),
(3, 'userB', '', '$2a$12$hL0rmIMjxhLqI.xr7jD1FugNWEgZNh62HuJj5.y34XBUfBWB4cppW', NULL),
(4, 'userC', '', '$2a$12$hL0rmIMjxhLqI.xr7jD1FugNWEgZNh62HuJj5.y34XBUfBWB4cppW', NULL),
(5, 'admin', '', '$2a$12$hL0rmIMjxhLqI.xr7jD1FugNWEgZNh62HuJj5.y34XBUfBWB4cppW', NULL);
现在有数据了,下面我们可以愉快的写代码了。
我们在控制器中创建
initializeAuthorizations() 方法,这个是用于初始化这个系统所有可用的权限。
namespace app\controllers;
use Yii;
use yii\web\Controller;
use yii\filters\AccessControl;
use app\models\User;
use app\models\LoginForm;
class MyAuthenticationController extends Controller
{
public function initializeAuthorizations()
{
$auth = Yii::$app->authManager;
$permissions = [
'createReservation' => array('desc' => 'Create a reservation'),
'updateReservation' => array('desc' => 'Update reservation'),
'deleteReservation' => array('desc' => 'Delete reservation'),
'createRoom' => array('desc' => 'Create a room'),
'updateRoom' => array('desc' => 'Update room'),
'deleteRoom' => array('desc' => 'Delete room'),
'createCustomer' => array('desc' => 'Create a customer'),
'updateCustomer' => array('desc' => 'Update customer'),
'deleteCustomer' => array('desc' => 'Delete customer'),
];
$roles = [
'operator' => array('createReservation', 'createRoom', 'createCustomer'),
];
// Add all permissions
foreach($permissions as $keyP=>$valueP)
{
$p = $auth->createPermission($keyP);
$p->description = $valueP['desc'];
$auth->add($p);
// add "operator" role and give this role the "createReservation" permission
$r = $auth->createRole('role_'.$keyP);
$r->description = $valueP['desc'];
$auth->add($r);
if( false == $auth->hasChild($r, $p)) $auth->addChild($r, $p);
}
// Add all roles
foreach($roles as $keyR=>$valueR)
{
$r = $auth->createRole($keyR);
$r->description = $keyR;
$auth->add($r);
foreach($valueR as $permissionName)
{
if( false == $auth->hasChild($r, $auth->getPermission($permissionName)))
$auth->addChild($r, $auth->getPermission($permissionName));
}
}
// Add all permissions to admin role
$r = $auth->createRole('admin');
$r->description = 'admin';
$auth->add($r);
foreach($permissions as $keyP=>$valueP)
{
if( false == $auth->hasChild($r, $auth->getPermission($permissionName)))
$auth->addChild($r, $auth->getPermission($keyP));
}
}
}
在上面的方法中,我们创建了 “
permissions
” 和 “
roles
”列表,然后把它们分配给Yii 的权限组件,
请确保你在第一时间声明了这个方法,
在每次使用
addChild() 时
调用
hasChild方法检查数据是否已存在,
我们为每个权限创建了一个角色,因为
assign
()和revoke()的
第一个参数
是一个角色,而不是一个权限,因此我们需要为每个权限复制一个角色。
接下来,我们可以创建actionIndex(),它启动先前初始化的授权,获取所有用户填充所有分配给每个用户的所有权限的数组。这是actionIndex()的内容方法:
public function actionIndex()
{
$auth = Yii::$app->authManager;
// Initialize authorizations
$this->initializeAuthorizations();
// Get all users
$users = User::find()->all();
// Initialize data
$rolesAvailable = $auth->getRoles();
$rolesNamesByUser = [];
// For each user, fill $rolesNames with name of roles assigned to user
foreach($users as $user)
{
$rolesNames = [];
$roles = $auth->getRolesByUser($user->id);
foreach($roles as $r)
{
$rolesNames[] = $r->name;
}
$rolesNamesByUser[$user->id] = $rolesNames;
}
return $this->render('index', ['users' => $users, 'rolesAvailable' =>
$rolesAvailable, 'rolesNamesByUser' => $rolesNamesByUser]);
}
创建 basic/views/authorization-manager/index.php 这个文件并写入以下内容:
<?php
use yii\helpers\Html;
?>
<table class="table">
<tr>
<td>User</td>
<?php foreach($rolesAvailable as $r) { ?>
<td><?php echo $r->description ?></td>
<?php } ?>
</tr>
<?php foreach($users as $u) { ?>
<tr>
<td><?php echo $u->username ?></td>
<?php foreach($rolesAvailable as $r) { ?>
<td align="center">
<?php if(in_array($r->name, $rolesNamesByUser[$u->id])) { ?>
<?php echo Html::a('Yes', ['remove-role', 'userId' => $u->id,
'roleName' => $r->name]); ?>
<?php } else { ?>
<?php echo Html::a('No', ['add-role', 'userId' => $u->id, 'roleName'
=> $r->name]); ?>
<?php } ?>
</td>
<?php } ?>
</tr>
<?php } ?>
</table>
每一个权限状态都关联到角色的添加和删除(取决于当前状态)
现在我们必须创建两个动作:为用户添加一个角色和删除一个角色:
public function actionAddRole($userId, $roleName)
{
$auth = Yii::$app->authManager;
$auth->assign($auth->getRole($roleName), $userId);
return $this->redirect(['index']);
}
public function actionRemoveRole($userId, $roleName)
{
$auth = Yii::$app->authManager;
$auth->revoke($auth->getRole($roleName), $userId);
return $this->redirect(['index']);
}