![](/img/trans.png)
[英]CRUD generated controllers and its actions are not called yii2 advanced
[英]Yii2 CORS with Auth not working for non CRUD actions
我正在 Yii2 中构建 API 并添加了 CORS 和身份验证。 这适用于所有创建/读取/更新/删除操作,但不适用于自定义操作。 有没有人经历过这种情况?
网址管理器:
['class' => 'yii\rest\UrlRule', 'controller' => 'api/v1/user', 'pluralize' => false],
控制器行为:
public function behaviors()
{
return ArrayHelper::merge([
'corsFilter' => [
'class' => Cors::className(),
],
[
'class' => HttpBearerAuth::className(),
'except' => ['options',
'login',
],
],
], parent::behaviors()
);
}
如前所述,CRUD 的操作很好,但是诸如http://domain.com/user/test
类的自定义操作将以401 Unauthorised
响应进行响应。
是否无法让 CORS 和 auth 在自定义操作上协同工作?
编辑:我应该补充一点,仅当浏览器发出OPTIONS
请求时才会出现问题 (401)。 正常请求(curl、Postman)不受影响。 问题似乎发生在 RESTful、Cors、Auth 组合中。
试试这个:
public function behaviors()
{
$behaviors = parent::behaviors();
unset($behaviors['authenticator']);
$behaviors['corsFilter'] = [
'class' => Cors::className(),
'cors' => [
'Origin' => ['*'],
'Access-Control-Request-Method' => ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD', 'OPTIONS'],
'Access-Control-Request-Headers' => ['*'],
'Access-Control-Allow-Credentials' => true,
],
];
$behaviors['authenticator'] = [
'class' => HttpBearerAuth::className(),
'except' => ['options','login'],
];
return $behaviors;
}
它将取消设置由父控制器实现的默认authenticator
器,以确保cors
处理cors
。 然后我们强制cors
在实现您自己的authenticator
之前允许凭据。
另一个可能引发Unauthorized错误的事情是未找到或错误的Options
响应,因为浏览器首先请求它获取允许的动词列表。 您可以在浏览器的网络选项卡中的标头响应中检查该列表。
一般规则是,当您要求浏览器对任何url执行诸如 PUT、DELETE 或 POST 之类的明智动词时,它可能会首先向同一个url发送 OPTIONS 请求(检查此)以在发送真实请求之前检查该动词是否被允许. 所以 Yii 应该被配置为通过执行正确的重定向来响应所有这些 OPTIONS 动词。
ActiveController
实现的默认 CRUD 操作使用这些默认模式:
'PUT,PATCH {id}' => 'update',
'DELETE {id}' => 'delete',
'GET,HEAD {id}' => 'view',
'POST' => 'create',
'GET,HEAD' => 'index',
'{id}' => 'options',
'' => 'options',
因此,无论您在urlManager['rules']
实现了何种配置,请务必不要覆盖其中的最后 2 个,并且如果您使用自定义模式,请始终记住包含其等效的options
动词,如本例所示:
[
'class' => 'yii\rest\UrlRule',
'controller' => ['account' => 'auth/account'],
'patterns' => [
'POST,HEAD login' => 'login',
'POST,HEAD signup' => 'signup',
'POST req-reset-pass' => 'request-password-reset',
'POST reset-pass' => 'reset-password',
// OPTTIONS VERBS
'OPTIONS login' => 'options',
'OPTIONS signup' => 'options',
'OPTIONS req-reset-pass' => 'options',
'OPTIONS reset-pass' => 'options',
]
],
在extraPatterns 中添加自定义模式时同样适用。
Options
操作默认在ActiveController
。 它的代码可以在这里看到。 如果你扩展了一个不同于ActiveController
控制器,比如\\yii\\rest\\Controller
一定要手动包含它:
public function actions()
{
$actions = parent::actions();
$actions['options'] = [
'class' => 'yii\rest\OptionsAction',
// optional:
'collectionOptions' => ['GET', 'POST', 'HEAD', 'OPTIONS'],
'resourceOptions' => ['GET', 'PUT', 'PATCH', 'DELETE', 'HEAD', 'OPTIONS'],
];
return $actions;
}
只需将您的 corsFilter 块移动到验证器块上方,如下所示:
public function behaviors()
{
return [
'corsFilter' => [
'class' => \yii\filters\Cors::className(),
],
'authenticator' => [
'class' => HttpBearerAuth::className(),
],
'contentNegotiator' => [
'class' => ContentNegotiator::className(),
'formats' => [
'application/json' => Response::FORMAT_JSON,
],
],
];
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.