我一直与Yii2 RBAC纠缠了一个星期,现在从各种站点收集信息,但我无法使其正常工作。我目前的情况包括两种方式:RBAC阻止所有内容,或者来宾可以访问所有内容。
我的主要问题是让RBAC允许用户访问分配给他们的页面。奇怪的是Yii::$app->user->can("/" . Yii::$app->controller->id . "/" . Yii::$app->controller->action->id);
函数为经过身份验证的用户正确返回true
,但是如果我将其嵌入到控制器的访问控制规则中,它将无法工作(给出403)。
return [
'access' => [
'class' => AccessControl::className(),
'rules' => [
[
'actions' => ['index', 'about', 'error', 'test'],
'allow' => true,
],
[
'actions' => ['login'],
'allow' => true,
'roles' => ['?'],
],
[
'actions' => ['logout'],
'allow' => true,
'roles' => ['@'],
],
[
'allow' => Yii::$app->user->can("/" . Yii::$app->controller->id . "/" . Yii::$app->controller->action->id),
'actions' => [Yii::$app->controller->action->id],
]
],
],
'verbs' => [
'class' => VerbFilter::className(),
'actions' => [
'logout' => ['post'],
],
],
];
我找到了解决此问题的方法,而不是将该条件硬编码到规则数组中,而是在return
命令之前插入一小段代码,如果用户确实可以,则将当前操作添加为通过array_merge
作为允许的操作访问该位置。现在可以正确应用经过身份验证的用户权限,但是,它始终为来宾返回true
(他们基本上拥有对所有内容的权限)。
$rules = [];
if (!Yii::$app->user->isGuest) {
if (Yii::$app->user->can("/" . Yii::$app->controller->id . "/" . Yii::$app->controller->action->id)) {
$rules[] = [
'allow' => true,
'actions' => [Yii::$app->controller->action->id],
];
}
}
return [
'access' => [
'class' => AccessControl::className(),
'rules' => array_merge($rules, [
[
'actions' => ['index', 'about', 'error', 'test'],
'allow' => true,
],
[
'actions' => ['login'],
'allow' => true,
'roles' => ['?'],
],
[
'actions' => ['logout'],
'allow' => true,
'roles' => ['@'],
],
]),
],
'verbs' => [
'class' => VerbFilter::className(),
'actions' => [
'logout' => ['post'],
],
],
];
我已经这样测试了访客权限:
var_dump(Yii::$app->user->can("/site/dashboard"));
die;
我执行的任何操作都会返回bool(true)
。如果我已登录,它将按照auth数据库表中的预期功能运行。
可以提供任何帮助,以发现我的解决方案中的错误或指出如何将RBAC与来宾和行为正确地使用。或者可能是为了帮助我理解为什么在没有经过身份验证的用户的情况下为什么返回true。
谢谢。
您的代码中的问题是您试图传递User
函数can()
错误的参数。在文档中指出:
can()公共方法检查用户是否可以执行以下操作:由给定的权限指定。
但是您尝试传递网址。
您必须在RBAC规则中分配如下权限:admin has
权限accessAdminDash
控制台/控制器/ RbacController
$auth = Yii::$app->authManager;
$dashboard = $auth->createPermission('accessAdminDash');
$dashboard->description = 'Admin manager panel';
$auth->add($dashboard);
//It can be more permissions
$admin = $auth->createRole('admin');
$admin->description = 'Administrator';
$admin->ruleName = $rule->name;
$auth->add($admin);
//Can be more Roles
//assign Permission to a role
$auth->addChild($admin, $dashboard);
然后,您可以像下面这样检查特定user
的权限:
Yii::$app->user->can('accessAdminDash'); //here is your permission
并且在执行控制器操作时,您可以检查或创建一个私有方法来检查当前用户:
if(Yii::$app->user->can('accessAdminDash'))
{
//Ok this user CAN access
}
throw new ForbiddenHttpException();
或在AccessControl中像这样检查角色:
public function behaviors()
{
return [
'access' => [
'class' => AccessControl::className(),
'rules' => [
[
'actions' => ['admin-page'],
'allow' => true,
'roles' => ['admin'], //Here is your role
]
],
],
];
}
希望这会给您正确的方向。