AngularJS使用REST对服务器端进行身份验证,并获取JSESSIONID cookie。 在下一步中,我尝试使用REST从服务器端获取一些JSON数据以及在上一步中获得的会话cookie。这是客户端代码:
getSomeJSONDataFromServer:function() {
var deferred = $q.defer();
$http({
method: 'POST',
withCredentials: true,
url: "http://domain.name/app/someURL",
headers:{
'Accept':'application/json',
'Content-Type':'application/json; charset=utf-8',
'Access-Control-Request-Headers': 'X-Requested-With, content-type, accept, origin, withcredentials'
}
})
.success(function(data, status, headers, config) {
// handle data
})
.error(function(data, status, headers, config) {
// handle error
});
return deferred.promise;
}
上面的代码工作正常:
当我在上面的POST请求体中发送一些数据时,问题就开始了。
...
$http({
method: 'POST',
withCredentials: true,
url: "http://domain.name/app/someURL",
headers:{
'Accept':'application/json',
'Content-Type':'application/json; charset=utf-8',
'Access-Control-Request-Headers': 'X-Requested-With, content-type, accept, origin, withcredentials'
},
data: '{}'
})
.success(...
上述代码在prelight请求中失败:
看起来服务器启动了一个新会话,因为会话cookie由于某种原因没有发送。无论如何,我觉得我错过了一些非常简单的东西,一些标题或类似的东西...... 任何想法都表示赞赏。提前谢谢。
答案 0 :(得分:7)
阿米尔,
请允许我帮助您和其他人清楚地了解在处理CORS时的预期结果:
这个简单的版本显然不是你的情况......
这个PREFLIGHTED版本显然是你的情况......
使用凭证的请求显然也是您的理由......
答案 1 :(得分:2)
根据Cross-Origin Request with Preflight specs凭据(即会话cookie)未在预检请求中发送,因此解决方案是禁用REST服务器端的OPTIONS请求的安全性,并仅允许没有会话cookie的请求用于OPTIONS请求。
当然要小心不要禁用POST和GET请求的安全性。
答案 2 :(得分:0)
根据https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS
为了在POST中允许cookie,需要使用Access-Control-Allow-Credentials配置远程:true。
如果您使用的是jetty,则需要配置
<init-param>
<param-name>allowCredentials</param-name>
<param-value>true</param-value>
</init-param>
引用MDN的文章,
重要说明:在响应凭证请求时,服务器必须指定域,并且不能使用通配符。如果标头被通配为:Access-Control-Allow-Origin:*,则上述示例将失败。由于Access-Control-Allow-Origin明确提及http://foo.example,因此凭据识别内容将返回到调用Web内容。