2014-11-05 146 views
1

我使用CakePHP作为后端,Angular作为前端,而前端&后端处于不同的域,所以这基本上是CORS情况。CORS - CakePHP不接受AngularJS JSON-请求

基本上我试图通过$ http.post发送一个表单的内容到一个Cake-API(稍后这是为了做认证部分 - 但我失败了)。因此,这里是代码:

aeapBackend.login = function(username, password) { 
    return $http.post(
     API_URL + 'api_mobile_user/login', { 
      test: username, 
      test2: password 
     } 
    ); 
}; 

而在CakePHP中相应的API看起来是这样的:

function beforeFilter() { 
    parent::beforeFilter(); 
    $this->Auth->allow(array('login')); 
} 

public function login() { 
    $this->response->header(array(
      'Access-Control-Allow-Origin' => '*', 
      'Access-Control-Allow-Headers' => 'Content-Type' 
     ) 
    ); 

    $this->autoRender = false; 
} 

会发生什么情况下一是预检OPTIONS请求IST完成 - 这看起来相当不错对我说:

请求报头:

OPTIONS /api_mobile_user/login HTTP/1.1 
Host: aeap.localhost 
Connection: keep-alive 
Access-Control-Request-Method: POST 
Origin: http://asf.localhost 
User-Agent: Mozilla/5.0 (iPhone; CPU iPhone OS 7_0 like Mac OS X; en-us) AppleWebKit/537.51.1 (KHTML, like Gecko) Version/7.0 Mobile/11A465 Safari/9537.53 
Access-Control-Request-Headers: accept, content-type 
Accept: */* 
Referer: http://asf.localhost/?username_input=hjk&password_input=hjgk&login_button= 
Accept-Encoding: gzip,deflate,sdch 
Accept-Language: de-DE,de;q=0.8,en-US;q=0.6,en;q=0.4 

响应头:

HTTP/1.1 200 OK 
Date: Wed, 05 Nov 2014 15:29:00 GMT 
Server: Apache/2.4.10 (Win32) OpenSSL/1.0.1i PHP/5.5.15 
X-Powered-By: PHP/5.5.15 
Set-Cookie: CAKEPHP=j6st0hnq8ear2cc6psg56d6eu3; expires=Wed, 05-Nov-2014 19:29:00 GMT; Max-Age=14400; path=/; HttpOnly 
Access-Control-Allow-Origin: * 
Access-Control-Allow-Headers: Content-Type 
Content-Length: 0 
Keep-Alive: timeout=5, max=100 
Connection: Keep-Alive 
Content-Type: text/html; charset=UTF-8 

但在实际POST请求,我得到一个状态码403完成:

XMLHttpRequest cannot load http://aeap.localhost/api_mobile_user/login. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://asf.localhost' is therefore not allowed access. The response had HTTP status code 403. 

我怎样才能避免这种情况?在我看来,我已经启用了CORS对Cake ['Access-Control-Allow-Origin']的支持。在我看来,AngularJS发布了一些额外的信息,这些信息在预检期间未被检查,然后被后端拒绝。

使用版本:2.5.3 CakePHP的,AngularJS:1.3.0

+2

我在CakePHP中有0经验,但它可以是您的服​​务器代码添加标题仅在“选项”(预检)进来时运行?另外,你发送了哪些头文件?他们都在“默认的HTTP头”列表或您明确配置的“内容类型”? – 2014-11-05 15:43:27

+0

@MarvinSmit:“content-type”被明确设置('Access-Control-Allow-Headers'=>'Content-Type'),否则预检将失败。当我使用$ http.get时,从后端获取数据没有任何困难,所以我假设头文件不仅仅是在预检期间设置的。无论如何谢谢你的评论 - 我会仔细检查一下。 – 2014-11-05 15:48:16

+1

我的意思是说,一个好的CORS实现将返回一个401/403,如果一个标题是用POST发送的,而不是它的'CORS'有效标题'列表。通过预检,您可以查看是否允许使用实际POST发送的标头(使用“request-headers” - >通过CORS实现以“allowed-headers”进行响应)。任何在“允许标题”或“默认HTTP标题”(根据CORS规范)之外发送的标题应该会导致“拒绝访问”。 – 2014-11-05 15:59:57

回答

1

感谢马文斯密特我能确定这是没有连接到CORS是报头中的行为的原因。我在Web服务器级别上设置了'Access-Control-Allow-Origin' => '*',所以我能够获得指向CakePHP安全组件的响应。

我基本上试图发送一个POST-Reuqest到一个没有期望数据应该发布给它的API。因此访问被拒绝。所以,我不得不添加$this->Security->csrfCheck = false到beforeFilter:

function beforeFilter() { 
    parent::beforeFilter(); 
    $this->Auth->allow(array('login')); 
    $this->Security->csrfCheck = false; 
} 
0

对于它的价值,为CakePHP的3做正确的方法是如下

public function beforeFilter() { 
    parent::beforeFilter(); 
    $this->Auth->allow(array('login')); 
    $this->eventManager()->off($this->Csrf); 
} 

虽然,这是不推荐的AJAX请求。以下文档可以帮助您更多。 CSRF And AJAX