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

时间:2017-05-29 08:46:22

标签: ajax rest yii2 cors basic-authentication

我开发了一个Yii2 REST API应用程序。当地的一切都很好。 我已将应用程序部署到远程服务器。我可以通过Postman获得api回复。但是当我尝试用AJAX或Angular发出请求时,我得到“预检的响应有无效的HTTP状态代码401”错误。 我的Controller behavior()方法:

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(),
        ],

    ]);
}

响应和请求标头:

enter image description here

enter image description here

enter image description here

我认为这是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;
    }
}

2 个答案:

答案 0 :(得分:1)

您需要为预检请求添加例外,如official docs

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

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

答案 1 :(得分:1)

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

.htaccess文件中的这两行完成了这一操作。

@NgModule({
    imports: [
              BrowserModule,
              FormsModule,
              HttpModule,
              MovieModule
    ],
    declarations: [AppComponent],
    bootstrap: [AppComponent]
})

export class AppModule {

}