Yii2 和 reactjs CORS 过滤器给出错误:预检响应具有无效的 HTTP 状态代码 401

Posted

技术标签:

【中文标题】Yii2 和 reactjs CORS 过滤器给出错误:预检响应具有无效的 HTTP 状态代码 401【英文标题】:Yii2 and reactjs CORS filters gives Error: Response for preflight has invalid HTTP status code 401 【发布时间】:2017-09-18 08:24:29 【问题描述】:

我正在尝试在 reactJs 中使用 ajax 请求来获取需要从 Yii2 中的 Bearer Auth 进行身份验证的资源。

请求标头

Accept: /Accept-Encoding: gzip、deflate、sdch、brAccept-Language : en-GB,en-US;q=0.8,en;q=0.6Access-Control-Request-Headers: 授权Access-Control -Request-Method: GETConnection: keep-aliveHost: localhostOrigin: http://localhost:8110Referer: http://localhost:8110/User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (Khtml, like Gecko) Chrome/57.0.2987.133 Safari/537.36

响应标头

Access-Control-Allow-Credentials: trueAccess-Control-Allow-Headers: 授权Access-Control-Allow-方法: GET、POST、PUT、OPTIONSAccess-Control-Allow-Origin: http://localhost:8110连接: Keep-Alive内容长度: 150内容类型: application/json; charset=UTF-8日期: 2017 年 4 月 21 日星期五 10:36:27 GMTKeep-Alive: timeout=5,max=99服务器: Apache/2.4.25 (Ubuntu)Www-Authenticate: Bearer realm="api"

这是我在yii2框架中的行为方法

public function behaviors()
  
        $behaviors = parent::behaviors();
        unset($behaviors['authenticator']);
        return [
                [
                    'class' => 'yii\filters\ContentNegotiator',
                    'only' => ['view', 'index', 'filters', 'slug', 'shortlist'],  // in a controller
                    // if in a module, use the following IDs for user actions
                    'formats' => [
                        'application/json' => Response::FORMAT_JSON,
                    ],
                ],
                'corsFilter' => [
                    'class' => \yii\filters\Cors::className(),
                    'cors' => [
                        'Origin' => ['*'],
                        'Access-Control-Request-Method' => ['GET', 'POST', 'PUT', 'OPTIONS'],
                        'Access-Control-Request-Headers' => ['*'],
                        'Access-Control-Allow-Credentials' => true,
                        ],
                ],
                'authenticator' => [
                        'class' => \yii\filters\auth\HttpBearerAuth::className(),
                        'except' => ['options'],
                ],
        ];
  

我知道与 CORS 相关的一些问题,因为 Postman 和 cURL(来自终端)使用相同的令牌,reactjs 和 ajax 显示相同的错误,所以相同的请求工作正常。

【问题讨论】:

【参考方案1】:

你的错误在于:

'except' => ['options'],

类“HttpBearerAuth”继承yii\base\ActionFilter,根据文档,该公共属性“$except”定义了“此过滤器不应应用的操作ID列表”。不是http方法。 因此,除了来自“身份验证器”的预检请求之外,上述内容将不包括您想要的 actionOptions() 请求。

您应该做的是避免为 OPTIONS http 请求返回 401 http 错误(这会导致您的错误),只返回 200 空响应。 您可以通过添加:

public function beforeAction($action)

    //your code

    if (Yii::$app->getRequest()->getMethod() === 'OPTIONS') 
        parent::beforeAction($action);
        Yii::$app->getResponse()->getHeaders()->set('Content-Type', 'text/plain');
        Yii::$app->end();
    

    return parent::beforeAction($action);

【讨论】:

显示一个空白页面,状态为 200 且无响应。没有出错,而且我的控制器中没有定义beforeAction 好的,我已经更新了。在控制器中添加 beforeAction 方法。 现在我所有的 CORS 标头都不起作用可能是因为第一个 beforeAction 正在执行并且当时没有 CORS。 实际上,您必须调用 parent::beforeAction() 才能将 CORS 标头添加到响应中。我更新了我的答案以包括这个。

以上是关于Yii2 和 reactjs CORS 过滤器给出错误:预检响应具有无效的 HTTP 状态代码 401的主要内容,如果未能解决你的问题,请参考以下文章

Yii2中如何允许CORS?

在 POST 请求中使用 Angular 和 Yii2 的 CORS 错误

Yii2 过滤具有多重关系的数据

PHP(Yii2)AngularJS的CORS问题

yii2项目实战-访问控制过滤器ACF讲解

Yii2过滤具有多个关系的数据