我现在正在尝试在Yii框架下开发一个网站,并且该程序需要基于角色的访问控制(RBAC(。我从指南中读到过滤器可用于 RBAC,但我想知道如果管理员和用户存储在两个表中,我该怎么办?也就是说,如果数据库中有两个表,一个用于管理员,一个用于用户,我应该如何实施访问控制?谢谢。
这是可能的。然而棘手,我不能保证这不会在未来带来问题。您需要的是有两个或多个表,例如AuthAssignment
,例如 AuthAssignment_Admins
和AuthAssignment_Customers
,并确保每次调用CDbAuthManager
时都引用相关的角色(例如,在分配角色或检查权限时(。
我会从很远的地方开始,但你会明白为什么。
-
我们必须创建一种机制来告诉登录用户属于哪个表/类别。这可以通过扩展
Yii::app()->user
来完成。在这里解释。您可能希望添加一个特殊的参数(例如authTable
(或与分配的模型进行比较。 -
你必须扩展
CDbAuthManager
.创建一个类,例如CDbAuthManagerTwoTables
在组件中,并在authManager
的config.php
中称为'class' => 'CDbAuthManagerTwoTables'
。在CDbAuthManagerTwoTables
<?php class CDbAuthManagerTwoTables extends CDbAuthManager { // public $assignmentTable = 'AuthAssignment'; public $assignmentTable = 'AuthAssignment_Customers'; // you may want to have AuthAssignment_Customers to be your default table function __construct() { if (!Yii::app()->user->isGuest) { if (Yii::app()->user->authTable == 'admin') { $this->assignmentTable = 'AuthAssignment_Admins'; } else { $this->assignmentTable = 'AuthAssignment_Customers'; } } } public function setType($assignmentTable = '') { // this method will be needed during authentication switch ($assignmentTable) { case 'Admin': $assignmentTable = 'AuthAssignment_Admins'; break; case 'Customer': $assignmentTable = 'AuthAssignment_Customers'; break; default: $assignmentTable = 'AuthAssignment_Customers'; break; } $this->assignmentTable = $assignmentTable; } }
-
现在在身份验证时分配。我们假设您已经有单独的登录表单,并且在
UserIdentity.php
中具有单独的方法。在代码中的某个地方,您将执行以下操作:$this->setState('authTable', 'admin'); $auth = Yii::app()->authManager; // You should already have this in your code $auth->setType('Admin'); // call to our new method from CDbAuthManagerTwoTables if (!$auth->isAssigned($user->role, $this->_id)) { if ($auth->assign($user->role, $this->_id)) { Yii::app()->authManager->save(); } }
-
没有步骤 4。
因此,Customers
或任何其他表格和授权也是如此。让我知道如果为你工作如何。
我认为这不可能开箱即用。当您检查身份验证分配的数据库模式时,您将看到它有一个 userid 字段,该字段与您的用户表相关。如果有两个不同的表,则身份验证表中需要另一个唯一标识符。是否绝对有必要为您的用户提供两个不同的表?实际上,RBAC 对于分离关注点非常有用。因此,您有一个用户表,但您可以为用户分配不同的角色,例如"管理员","编辑者"等。如果您有两个不同的用户表,如果用户成为管理员,该怎么办?这是您不应该处理的复杂性。如果绝对必须这样做,则必须扩展 RBAC 功能,以便能够引用不同的表。
更改用户 ID 的存储方式
我目前正在处理这个确切的问题,我的解决方案是修改用户 ID 在分配表中的存储方式。我不是只存储一个整数用户 ID,而是存储一个指示 ID 和用户类型的字符串:
auth_assignments.userid["<typeId>.<userId>"] VARCHAR(64) NOT NULL
分配或检查角色时,将使用用户的"授权 ID"而不是其正常 ID。 很想听到有关此方法的反馈。