对 Restful API 请求使用 Yii2 RBAC
Use Yii2 RBAC for Restful API request
我开发了一个基于 Yii2 框架的网络应用程序。 Web 应用程序使用 RBAC 系统根据用户类型(管理员、员工、子员工)进行操作授权。现在我正在开发一个移动应用程序,我为这个移动应用程序调用的控制器创建了一个新模块 "mobile"。在这些新控制器中,我使用 CORS 和身份验证器设置了行为函数,这些都没有问题。我还设置了 RBAC 系统,就像我为网络应用所做的那样,但在移动模块中不起作用。有人可以帮我设置 controller/action 的权限吗?
public function behaviors()
{
$behaviors = parent::behaviors();
$behaviors['authenticator'] = [
'class' => CompositeAuth::className(),
'except' => ['index','view','test'],
'authMethods' => [
HttpBearerAuth::className(),
HttpBasicAuth::className(),
// QueryParamAuth::className(),
],
];
$auth = $behaviors['authenticator'];
unset($behaviors['authenticator']);
$behaviors['corsFilter'] =
[
'class' => \yii\filters\Cors::className(),
'cors' => [
// restrict access to
'Origin' => ['*'],
// Allow only POST and PUT methods
'Access-Control-Request-Method' => ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS'],
// // Allow only headers 'X-Wsse'
'Access-Control-Request-Headers' => ['*'],
// // Allow credentials (cookies, authorization headers, etc.) to be exposed to the browser
'Access-Control-Allow-Credentials' => false,
// // Allow OPTIONS caching
'Access-Control-Max-Age' => 3600,
// // Allow the X-Pagination-Current-Page header to be exposed to the browser.
'Access-Control-Expose-Headers' => ['X-Pagination-Current-Page'],
],
];
$behaviors['authenticator'] = $auth;
// avoid authentication on CORS-pre-flight requests (HTTP OPTIONS method)
// $behaviors['authenticator']['except'] = ['OPTIONS', 'login'];
$behaviors['access'] =
[
'class' => AccessControl::className(),
'rules' => [
[
'allow' => true,
'actions' => ['create','view','update','delete','index', 'logout'],
'roles' => ['@'],
'denyCallback' => function ($rule, $action) {
throw new \yii\web\ForbiddenHttpException('You are not allowed to access this page');
}
],
[
'allow' => true,
'actions' => ['login', 'index','test'],
'roles' => ['?'],
'denyCallback' => function ($rule, $action) {
throw new \yii\web\ForbiddenHttpException('You are not allowed to access this page');
}
],
],
];
return $behaviors;
}
覆盖 ActiveController()
的 checkAccess()
方法
当您使用 yii\rest\ActiveController
时,$behaviors['access']
不是检查访问权限的正确方法,您应该重写 checkAccess()
方法。
操作示例:
/**
* Checks the privilege of the current user.
*
* This method should be overridden to check whether the current user has the privilege
* to run the specified action against the specified data model.
* If the user does not have access, a [[ForbiddenHttpException]] should be thrown.
*
* @param string $action the ID of the action to be executed
* @param \yii\base\Model $model the model to be accessed. If `null`, it means no specific model is being accessed.
* @param array $params additional parameters
* @throws ForbiddenHttpException if the user does not have access
*/
public function checkAccess($action, $model = null, $params = [])
{
// You could completely block some actions
if ($action === 'delete') {
throw new ForbiddenHttpException(
Yii::t('app',
'You are not allowed to {action} client models.',
['action' => $action]
)
);
}
// You could check if the current user has permission to run the action
if ($action === 'index' && !Yii::$app->user->can('listClients')) {
throw new ForbiddenHttpException(Yii::t('app',
'You are not allowed to list clients'));
}
// You can also make the check more granular based on the model being accessed
if ($action === 'view' &&
!Yii::$app->user->can('viewClient', ['client_id' => $model->id])) {
throw new ForbiddenHttpException(Yii::t('app',
'You are not allowed to view client {client}',
['client' => $model->id]));
}
}
查看您的示例,您似乎只检查经过身份验证的用户 @
或未经过身份验证的用户、来宾 ?
。
这有点令人困惑,因为它在 yii\web\Controller
上有所不同,但您不应该检查用户是否在 checkAccess()
上进行了身份验证,该检查已由 [=22] 执行=] 过滤器,使用您随问题发布的代码,在 checkAccess()
被调用时,您将始终拥有应用程序用户,因此 @
将 始终 匹配,而 ?
将 永远不会 匹配。
由于您注释掉了以下行:
// $behaviors['authenticator']['except'] = ['OPTIONS', 'login'];
这意味着 CORS 飞行前请求将始终失败,并且来宾用户将永远无法登录。任何未通过身份验证的请求将立即导致 401 unauthorized
响应。
您似乎试图让所有经过身份验证的用户访问所有操作,而未经身份验证的用户仅访问 login、index 和 测试 动作。如果那是正确的,你不需要使用 checkAccess()
方法,你可以取消注释上面的行并在那里添加操作,如下所示:
$behaviors['authenticator']['except'] = ['options', 'login', 'index', 'test'];
未经身份验证的用户将只能访问这些操作。
我开发了一个基于 Yii2 框架的网络应用程序。 Web 应用程序使用 RBAC 系统根据用户类型(管理员、员工、子员工)进行操作授权。现在我正在开发一个移动应用程序,我为这个移动应用程序调用的控制器创建了一个新模块 "mobile"。在这些新控制器中,我使用 CORS 和身份验证器设置了行为函数,这些都没有问题。我还设置了 RBAC 系统,就像我为网络应用所做的那样,但在移动模块中不起作用。有人可以帮我设置 controller/action 的权限吗?
public function behaviors()
{
$behaviors = parent::behaviors();
$behaviors['authenticator'] = [
'class' => CompositeAuth::className(),
'except' => ['index','view','test'],
'authMethods' => [
HttpBearerAuth::className(),
HttpBasicAuth::className(),
// QueryParamAuth::className(),
],
];
$auth = $behaviors['authenticator'];
unset($behaviors['authenticator']);
$behaviors['corsFilter'] =
[
'class' => \yii\filters\Cors::className(),
'cors' => [
// restrict access to
'Origin' => ['*'],
// Allow only POST and PUT methods
'Access-Control-Request-Method' => ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS'],
// // Allow only headers 'X-Wsse'
'Access-Control-Request-Headers' => ['*'],
// // Allow credentials (cookies, authorization headers, etc.) to be exposed to the browser
'Access-Control-Allow-Credentials' => false,
// // Allow OPTIONS caching
'Access-Control-Max-Age' => 3600,
// // Allow the X-Pagination-Current-Page header to be exposed to the browser.
'Access-Control-Expose-Headers' => ['X-Pagination-Current-Page'],
],
];
$behaviors['authenticator'] = $auth;
// avoid authentication on CORS-pre-flight requests (HTTP OPTIONS method)
// $behaviors['authenticator']['except'] = ['OPTIONS', 'login'];
$behaviors['access'] =
[
'class' => AccessControl::className(),
'rules' => [
[
'allow' => true,
'actions' => ['create','view','update','delete','index', 'logout'],
'roles' => ['@'],
'denyCallback' => function ($rule, $action) {
throw new \yii\web\ForbiddenHttpException('You are not allowed to access this page');
}
],
[
'allow' => true,
'actions' => ['login', 'index','test'],
'roles' => ['?'],
'denyCallback' => function ($rule, $action) {
throw new \yii\web\ForbiddenHttpException('You are not allowed to access this page');
}
],
],
];
return $behaviors;
}
覆盖 ActiveController()
的 checkAccess()
方法
当您使用 yii\rest\ActiveController
时,$behaviors['access']
不是检查访问权限的正确方法,您应该重写 checkAccess()
方法。
操作示例:
/**
* Checks the privilege of the current user.
*
* This method should be overridden to check whether the current user has the privilege
* to run the specified action against the specified data model.
* If the user does not have access, a [[ForbiddenHttpException]] should be thrown.
*
* @param string $action the ID of the action to be executed
* @param \yii\base\Model $model the model to be accessed. If `null`, it means no specific model is being accessed.
* @param array $params additional parameters
* @throws ForbiddenHttpException if the user does not have access
*/
public function checkAccess($action, $model = null, $params = [])
{
// You could completely block some actions
if ($action === 'delete') {
throw new ForbiddenHttpException(
Yii::t('app',
'You are not allowed to {action} client models.',
['action' => $action]
)
);
}
// You could check if the current user has permission to run the action
if ($action === 'index' && !Yii::$app->user->can('listClients')) {
throw new ForbiddenHttpException(Yii::t('app',
'You are not allowed to list clients'));
}
// You can also make the check more granular based on the model being accessed
if ($action === 'view' &&
!Yii::$app->user->can('viewClient', ['client_id' => $model->id])) {
throw new ForbiddenHttpException(Yii::t('app',
'You are not allowed to view client {client}',
['client' => $model->id]));
}
}
查看您的示例,您似乎只检查经过身份验证的用户 @
或未经过身份验证的用户、来宾 ?
。
这有点令人困惑,因为它在 yii\web\Controller
上有所不同,但您不应该检查用户是否在 checkAccess()
上进行了身份验证,该检查已由 [=22] 执行=] 过滤器,使用您随问题发布的代码,在 checkAccess()
被调用时,您将始终拥有应用程序用户,因此 @
将 始终 匹配,而 ?
将 永远不会 匹配。
由于您注释掉了以下行:
// $behaviors['authenticator']['except'] = ['OPTIONS', 'login'];
这意味着 CORS 飞行前请求将始终失败,并且来宾用户将永远无法登录。任何未通过身份验证的请求将立即导致 401 unauthorized
响应。
您似乎试图让所有经过身份验证的用户访问所有操作,而未经身份验证的用户仅访问 login、index 和 测试 动作。如果那是正确的,你不需要使用 checkAccess()
方法,你可以取消注释上面的行并在那里添加操作,如下所示:
$behaviors['authenticator']['except'] = ['options', 'login', 'index', 'test'];
未经身份验证的用户将只能访问这些操作。