远程服务器上的 YII 2 REST CORS 问题

Posted

技术标签:

【中文标题】远程服务器上的 YII 2 REST CORS 问题【英文标题】:YII 2 REST CORS issue on remote server 【发布时间】:2017-10-29 12:13:48 【问题描述】:

我开发了一个 Yii2 REST API 应用程序。在本地一切正常。 我已将应用程序部署到远程服务器。我可以通过 Postman 获得 api 响应。但是当我尝试使用 AJAX 或 Angular 发出请求时,我收到“预检响应具有无效的 HTTP 状态代码 401”错误。 我的控制器行为()方法:

public function behaviors() 

    return array_merge(parent::behaviors(), [


        $behaviors['corsFilter']  = [
            'class' => \yii\filters\Cors::className(),
            'cors'  => [
                // restrict access to domains:
                'Origin'                           => ['*'],
                'Access-Control-Request-Method'    => ['GET','POST','PUT','DELETE','OPTIONS'],
                'Access-Control-Request-Headers' => ['*'],
                'Access-Control-Allow-Credentials' => true,
                'Access-Control-Max-Age'           => 3600,                 // Cache (seconds)
            ],
        ],
        $behaviors['authenticator'] = [
            'class' => AvnrHttpBasicAuth::className(),
        ],

    ]);

响应和请求标头:

我认为这是 CORS 问题,但我无法弄清楚为什么这在使用 apache 的 Centos 上运行的远程服务器上不起作用。

我已经扩展了 HttpBasicAuth 并使用了我自己的 AvnrHttpBasicAuth 类

class AvnrHttpBasicAuth extends HttpBasicAuth

    public function authenticate($user, $request, $response)
    

        $authHeader = $request->getHeaders()->get('Authorization');

        if ($authHeader !== null && preg_match("/^Basic\\s+(.*?)$/", $authHeader, $matches)) 

            $identity = $user->loginByAccessToken($matches[1], get_class($this));

            if ($identity === null) 
                $this->handleFailure($response);
            
            return $identity;
        
        return null;
    

【问题讨论】:

【参考方案1】:

我通过对我的 .htaccess 文件稍作修改解决了这个问题。 感谢这个post

.htaccess 文件中的这两行代码起到了作用。

RewriteCond %REQUEST_METHOD OPTIONS
RewriteRule ^(.*)$ $1 [R=200,L]
Header always set Access-Control-Allow-Origin "*"

【讨论】:

这将允许来自任何来源的请求。【参考方案2】:

您需要为预检请求添加一个例外,如official docs 所示:

$behaviors['authenticator'] = [
    'class' => AvnrHttpBasicAuth::className(),
    'except' => ['options']
],

Preflight Requests 在需要时由浏览器处理/发出。例如,当前端和后端托管在不同的域中并且您正在发出 POST 请求时,浏览器需要先发送一个 OPTIONS 请求以查看是否允许 POST,然后再发送真正的请求。要从 POSTMAN 测试它,您需要发送一个 OPTIONS 请求而不是 POST/PUT。

【讨论】:

我添加了 'except' => ['options'] 异常但还是一样。 怎么XXX.XXX.73.161/~dsltrading/v1/web/api/customer/view?id=1返回: 405 "Method Not Allowed. 这个url只能处理以下请求方法: GET, HEAD 我假设 AvnrHttpBasicAuth 有一个 except 属性作为所有 Yii2 官方过滤器。但它可能没有。我不知道那是什么图书馆。 你在扩展什么控制器?是活动控制器吗?那是什么服务器?如果 IIS 我认为您需要将其配置为允许这些动词 我正在扩展 ApiController(我自己的控制器),其中 ApiController 从 ActiveController 扩展我已经修改了我的问题并添加了我的 AvnrHttpBasicAuth 类。

以上是关于远程服务器上的 YII 2 REST CORS 问题的主要内容,如果未能解决你的问题,请参考以下文章

Tomcat REST API 上的 CORS 访问

从其他域(jquery ajax)访问托管在 aws ec2 上的 rest 服务但出现 CORS 错误

Yii 和 Vue2 CORS 启用。服务器以 404 错误响应预检 OPTIONS 请求

使用 FireFox 从 localhost 到 REST 服务的 XMLHttpRequest 的 CORS 问题

从家庭网络上的 grunt Web 服务器限制 http:// 连接到远程托管 Web 服务器的正确 CORS 条目是啥?

如何使用 Spring Java Mongo REST 应用程序配置 CORS?