Yii2中模块的访问控制
Access control of a Module in Yii2
我在登录部分遇到问题。
我读了这个主题:http://www.yiiframework.com/wiki/771/rbac-super-simple-with-admin-and-user/。
然后我按照它的步骤,但在第 6 步。它只配置一个控制器。我有一个名为 Admin 的模块,其中包含许多控制器,但我不知道如何将此访问控制应用于整个模块。谁能帮我 ?
抱歉我的英语不好。
您可以创建 AdminController
class,这将扩展 yii\web\Controller
您在 behaviors
方法中定义访问规则的位置,并使其他模块控制器扩展您的 AdminController
并像这样覆盖 behaviors
方法:
public function behaviors()
{
return \yii\helpers\ArrayHelper::merge(parent::behaviors(), [
'verbs' => [
'class' => VerbFilter::className(),
'actions' => [
'delete' => ['post'],
],
],
]);
}
这里 parent::behaviors()
是来自 AdminController
的定义默认访问规则的行为,您将它们与子控制器中的特定行为合并。它使您可以根据需要灵活地覆盖某些访问规则。
制作自定义模型AccessRules.php
如下图:
<?php
namespace app\models;
class AccessRules extends \yii\filters\AccessRule
{
/**
* @inheritdoc
*/
protected function matchRole($user)
{
if (empty($this->roles)) {
return true;
}
foreach ($this->roles as $role) {
if ($role === '?') {
if ($user->getIsGuest()) {
return true;
}
} elseif ($role === '@') {
if (!$user->getIsGuest()) {
return true;
}
// Check if the user is logged in, and the roles match
} elseif (!$user->getIsGuest() && (int)$role === $user->identity->user_role) {
return true;
}
}
return false;
}
}
?>
现在打开您的站点控制器并在功能行为部分添加以下代码:
use app\models\AccessRules;
public function behaviors()
{
return [
'access' => [
'class' => AccessControl::className(),
// We will override the default rule config with the new AccessRule class
'ruleConfig' => [
'class' => AccessRules::className(),
],
'only' => ['create', 'update', 'delete','index'],
'rules' => [
[
'actions' => ['create', 'update', 'delete','index'],
'allow' => true,
// Allow admin to create
'roles' => [
'1'
],
]
],
],
'verbs' => [
'class' => VerbFilter::className(),
'actions' => [
'logout' => ['post'],
],
],
];
}
我可以根据您提到的文章提出一种变体方法。
按照描述执行前 2 个步骤,然后执行以下操作:
1. 将字段 role
添加到 User 模型并使用文章示例中的常量之一的值对其进行评估 (User::ROLE_ADMIN 或 User::ROLE_USER)
2. 覆盖 yii\web\User->can()
public function can($permissionName, $params = [], $allowCaching = true)
{
/** @var \app\models\User $user */
$user = $this->identity;
$access = false;
do {
if (\Yii::$app->user->isGuest) {
break;
}
if ($user->role === \common\models\User::ROLE_ADMIN) {
$access = true;
break;
}
if (is_array($permissionName)) {
$access = in_array($user->role, $permissionName);
} else {
$access = $permissionName === $user->role;
}
} while (false);
return $access;
}
所以现在您可以像这样检查用户的角色:
\Yii::$app->user->can(User::ROLE_USER)
3. 你说:
i don't know how to apply this access control to the whole module.
然后打开您的模块 class 并将以下内容添加到 behaviors() 方法中:
public function behaviors()
{
return [
'access' => [
'class' => AccessControl::className(),
'rules' => [
[
'allow' => true,
'roles' => [User::ROLE_ADMIN]
]
]
]
];
}
在本例中,我们将 ROLE_ADMIN 的访问权限授予您模块的所有控制器的所有操作。
就是这样。
根据 Yii2 Guide
"ACF is an action filter that can be used in a controller or a module"同理
只需在要限制功能的控制器中添加以下代码
'access' => [
'class' => AccessControl::className(),
'rules' =>
[
[
'actions' => ['index','view'],
'allow' => true,
'roles' => ['@']
],
[
'actions' => ['create','update','delete'],
'allow' => true,
'roles' => ['@'],
'matchCallback' => function ($rule, $action)
{
return Admin::isUserAdmin(Yii::$app->user->identity->username);
}
],
],
],
我在登录部分遇到问题。 我读了这个主题:http://www.yiiframework.com/wiki/771/rbac-super-simple-with-admin-and-user/。 然后我按照它的步骤,但在第 6 步。它只配置一个控制器。我有一个名为 Admin 的模块,其中包含许多控制器,但我不知道如何将此访问控制应用于整个模块。谁能帮我 ? 抱歉我的英语不好。
您可以创建 AdminController
class,这将扩展 yii\web\Controller
您在 behaviors
方法中定义访问规则的位置,并使其他模块控制器扩展您的 AdminController
并像这样覆盖 behaviors
方法:
public function behaviors()
{
return \yii\helpers\ArrayHelper::merge(parent::behaviors(), [
'verbs' => [
'class' => VerbFilter::className(),
'actions' => [
'delete' => ['post'],
],
],
]);
}
这里 parent::behaviors()
是来自 AdminController
的定义默认访问规则的行为,您将它们与子控制器中的特定行为合并。它使您可以根据需要灵活地覆盖某些访问规则。
制作自定义模型AccessRules.php
如下图:
<?php
namespace app\models;
class AccessRules extends \yii\filters\AccessRule
{
/**
* @inheritdoc
*/
protected function matchRole($user)
{
if (empty($this->roles)) {
return true;
}
foreach ($this->roles as $role) {
if ($role === '?') {
if ($user->getIsGuest()) {
return true;
}
} elseif ($role === '@') {
if (!$user->getIsGuest()) {
return true;
}
// Check if the user is logged in, and the roles match
} elseif (!$user->getIsGuest() && (int)$role === $user->identity->user_role) {
return true;
}
}
return false;
}
}
?>
现在打开您的站点控制器并在功能行为部分添加以下代码:
use app\models\AccessRules;
public function behaviors()
{
return [
'access' => [
'class' => AccessControl::className(),
// We will override the default rule config with the new AccessRule class
'ruleConfig' => [
'class' => AccessRules::className(),
],
'only' => ['create', 'update', 'delete','index'],
'rules' => [
[
'actions' => ['create', 'update', 'delete','index'],
'allow' => true,
// Allow admin to create
'roles' => [
'1'
],
]
],
],
'verbs' => [
'class' => VerbFilter::className(),
'actions' => [
'logout' => ['post'],
],
],
];
}
我可以根据您提到的文章提出一种变体方法。 按照描述执行前 2 个步骤,然后执行以下操作:
1. 将字段 role
添加到 User 模型并使用文章示例中的常量之一的值对其进行评估 (User::ROLE_ADMIN 或 User::ROLE_USER)
2. 覆盖 yii\web\User->can()
public function can($permissionName, $params = [], $allowCaching = true)
{
/** @var \app\models\User $user */
$user = $this->identity;
$access = false;
do {
if (\Yii::$app->user->isGuest) {
break;
}
if ($user->role === \common\models\User::ROLE_ADMIN) {
$access = true;
break;
}
if (is_array($permissionName)) {
$access = in_array($user->role, $permissionName);
} else {
$access = $permissionName === $user->role;
}
} while (false);
return $access;
}
所以现在您可以像这样检查用户的角色:
\Yii::$app->user->can(User::ROLE_USER)
3. 你说:
i don't know how to apply this access control to the whole module.
然后打开您的模块 class 并将以下内容添加到 behaviors() 方法中:
public function behaviors()
{
return [
'access' => [
'class' => AccessControl::className(),
'rules' => [
[
'allow' => true,
'roles' => [User::ROLE_ADMIN]
]
]
]
];
}
在本例中,我们将 ROLE_ADMIN 的访问权限授予您模块的所有控制器的所有操作。 就是这样。
根据 Yii2 Guide "ACF is an action filter that can be used in a controller or a module"同理
只需在要限制功能的控制器中添加以下代码
'access' => [
'class' => AccessControl::className(),
'rules' =>
[
[
'actions' => ['index','view'],
'allow' => true,
'roles' => ['@']
],
[
'actions' => ['create','update','delete'],
'allow' => true,
'roles' => ['@'],
'matchCallback' => function ($rule, $action)
{
return Admin::isUserAdmin(Yii::$app->user->identity->username);
}
],
],
],