[英]Yii2 + restapi + cors + bearer - unauthorized when creating custom controller action
我正在制作角度2 / Yii2应用程序
当我从带有承载标题的Postman调用自定义控制器/动作时,一切正常,但是当我使用来自angular 2应用程序(localhost:4200)的相同标头调用它时,我总是得到Unauthorized 401错误。 当我执行标准操作时,例如来自指南中的示例:
GET /users: list all users page by page;
POST /users: create a new user;
一切正常,只有当我创建自定义动作时,才会被我未经授权。
这是跨域应用程序,angular可在web.example.com上获得,yii2 app在srv.example.com上
namespace app\controllers\restapi;
use yii\filters\auth\CompositeAuth;
use yii\filters\auth\HttpBearerAuth;
class SearchOrderController extends \yii\rest\Controller
{
public $modelClass = 'app\models\Order';
public function behaviors()
{
$behaviors = parent::behaviors();
$auth = $behaviors['authenticator'];
unset($behaviors['authenticator']);
$behaviors['corsFilter'] = [
'class' => \yii\filters\Cors::className(),
];
$behaviors['authenticator'] = [
'class' => CompositeAuth::className(),
'authMethods' => [
HttpBearerAuth::className(),
],
];
// avoid authentication on CORS-pre-flight requests (HTTP OPTIONS method)
return $behaviors;
}
public function actionSearch(){
\Yii::$app->response->format=\yii\web\Response::FORMAT_JSON;
return ['index'=>'some text', 'value'=>123];
}
}
我的网址管理员:
[
'class' => 'yii\rest\UrlRule',
'controller' => 'order',
'pluralize' => false,
'extraPatterns' => [
'GET order/<id:\id+>' => 'order/view',
]
],
[
'class' => 'yii\rest\UrlRule',
'controller' => 'search-order',
'pluralize' => false,
'extraPatterns' => [
'GET search-order/search' => 'search-order/search',
]
我使用此处发布的解决方案解决了我的问题:
并实现自定义Cors类:
<?php
namespace app\components;
use Yii;
use yii\filters\Cors;
class CustomCors extends Cors
{
public function beforeAction($action)
{
parent::beforeAction($action);
if (Yii::$app->getRequest()->getMethod() === 'OPTIONS') {
Yii::$app->getResponse()->getHeaders()->set('Allow', 'POST GET PUT');
Yii::$app->end();
}
return true;
}
}
并相应地改变我的控制器行为:
public function behaviors()
{
$behaviors = parent::behaviors();
// remove authentication filter
$auth = $behaviors['authenticator'];
unset($behaviors['authenticator']);
// add CORS filter
$behaviors['corsFilter'] = [
'class' =>CustomCors::className()
];
// re-add authentication filter
$behaviors['authenticator'] = [
'class' => CompositeAuth::className(),
'authMethods' => [
HttpBearerAuth::className(),
],
];
return $behaviors;
}
它看起来像是一个预检请求问题。 我在这里看到两件事要解决。
首先,当您扩展yii\\rest\\Controller
需要实现响应该请求的操作。 这样的动作已由Yii实现,但在其子控制器yii\\rest\\ActiveController
。 所以要么你使用actions()
函数来导入它就像在这里完成一样,或者你可以直接实现它,因为它在这个其他的satck溢出帖子中完成:
Post Post在Postman中工作,但在Angular 2 app中返回Preflight错误
然后你需要定义他们的相关规则:
[
'class' => 'yii\rest\UrlRule',
'controller' => 'order',
'pluralize' => false,
'extraPatterns' => [
'GET order/<id:\id+>' => 'order/view',
'OPTIONS order/<id:\id+>' => 'order/options',
]
],
[
'class' => 'yii\rest\UrlRule',
'controller' => 'search-order',
'pluralize' => false,
'extraPatterns' => [
'GET search-order/search' => 'search-order/search',
'OPTIONS search-order/search' => 'search-order/options',
]
接下来,您需要让您的身份验证允许预检请求,因为浏览器不会发送任何令牌。 通过添加此行,如官方文档中所示:
// avoid authentication on CORS-pre-flight requests (HTTP OPTIONS method)
$behaviors['authenticator']['except'] = ['options'];
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.