CakePHP2:JWT Auth的CORS预检问题

时间:2016-12-29 19:15:55

标签: php angularjs http cakephp cors

我正在构建一个Ionic 1应用程序,它与CakePHP 2.8中实现的REST API进行对话,使用JSON Web Tokens (JWT)进行身份验证。

在未经授权的状态下,我的应用程序能够毫无问题地向服务器发出GET / POST请求。但是,一旦我通过身份验证并且我的应用程序正在发送authToken标头以及每个请求,Angular会首先自动发送OPTIONS预检请求。

这是问题的开始。由于自动预检请求没有设置authToken标头,并且由于API端点需要授权,因此CakePHP以302 FOUND重定向响应/login。应用程序(或浏览器,在此测试阶段)认为这是不安全的,并且永远不会继续提出正确的请求。

我的问题:如何让CakePHP对预检OPTIONS请求作出适当的响应,以便AngularJS知道它可以安全地将自定义标头发送到跨域服务器?

this question,这是需要发生的事情:

请求标题:

Origin: http://yourdomain.com
Access-Control-Request-Method: POST
Access-Control-Request-Headers: X-Custom-Header

回复标题:

Access-Control-Allow-Origin: http://yourdomain.com // Same as origin above
Access-Control-Allow-Methods: GET, POST
Access-Control-Allow-Headers: X-Custom-Header

我尝试过的事情:

- 设置.htaccess始终使用OPTIONS回复200次请求。我得到200响应,但响应显示“您的服务器配置错误”,并且由于没有设置正确的标头,真正的$http请求永远不会通过。

- 获取CakePHP始终以某种方式响应OPTIONS个请求。这里的问题是让Cake跳过授权,跳过尝试运行控制器操作,并发回一个带有正确标头集的HTTP 200响应。

    // AppController::beforeFilter();
    if($this->request->is("options")){
        // Send the appropriate response based on the request
    }

对于好奇,这里是在失败的$http请求过程中交换的标题:

GENERAL:
Request URL:https://api.example.com/rest_users/profile.json
Request Method:OPTIONS
Status Code:302 Found
Remote Address:x.x.x.x:443

REQUEST HEADERS:
Accept:*/*
Accept-Encoding:gzip, deflate, sdch, br
Accept-Language:en-US
Access-Control-Request-Headers:authtoken
Access-Control-Request-Method:GET
Cache-Control:no-cache
Connection:keep-alive
DNT:1
Host:api.example.com
Origin:http://x.x.x.x:8100
Pragma:no-cache
Referer:http://x.x.x.x:8100/
User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.95 Safari/537.36


RESPONSE HEADERS:
Access-Control-Allow-Headers:Content-Type, x-xsrf-token
Access-Control-Allow-Methods:*
Access-Control-Allow-Origin:*
Access-Control-Max-Age:172800
Connection:Keep-Alive
Content-Encoding:gzip
Content-Length:20
Content-Type:text/html; charset=UTF-8
Date:Thu, 29 Dec 2016 18:51:30 GMT
Keep-Alive:timeout=15, max=99
Location:https://api.example.com/login
Server:Apache/2.2.15 (CentOS)
Vary:Accept-Encoding
X-Powered-By:PHP/5.3.3

1 个答案:

答案 0 :(得分:1)

我找到了一个允许CakePHP正确处理CORS预检的解决方案。它设置标头,发送响应,并在请求的操作可以运行之前关闭Cake。

确保所有控制器都有parent::beforeFilter();,以便运行此代码。

在AppController :: beforeFilter()中:

    if($this->request->is("options")){
        // Set the headers
        $this->response->header('Access-Control-Allow-Origin','*');
        $this->response->header('Access-Control-Allow-Methods','*');
        $this->response->header('Access-Control-Allow-Headers','Content-Type, Authorization');
        // Send the response
        $this->response->send();
        // Don't do anything else!
        $this->_stop();
    }