HTTP标头设置授权标头阻止数据加载
Posted
技术标签:
【中文标题】HTTP标头设置授权标头阻止数据加载【英文标题】:HTTP Headers setting Authorization header stops data from loading 【发布时间】:2013-11-14 08:30:15 【问题描述】:我正在使用 Ember.js、Ember Simple Auth 插件和 jQuery 使用 ajax 跨域发送 Authorization
标头。当设置Authorization
标头时:
jqXHR.setRequestHeader('Authorization', 'Bearer ' + session.get('authToken'));
然后我收到一个发送到 REST URL 的飞行前OPTIONS
请求,然后我返回以下标头:
$headers->set('Access-Control-Allow-Origin', 'http://subdomain2.domain.com');
$headers->set('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS');
$headers->set('Access-Control-Allow-Headers', 'Content-Type, Authorization, Accept');
$headers->set('Access-Control-Max-Age', 10);
$headers->set('Content-Length', 0);
在 Chrome 网络监视器中,此 OPTIONS
请求返回成功。然后,当 GET 请求在飞行前 OPTIONS
请求之后出现时,GET
请求只是挂起或至少在网络监视器中显示 (pending)
:
如果我在几秒钟后刷新页面,页面会显示,但它不会在OPTIONS
调用后立即显示。
当我使用Access-Control-Max-Age
标头并增加缓存时间时,我可以在它再次发送OPTIONS
调用之前刷新多次,这意味着页面将显示得很好。只有当OPTIONS
调用与GET
一起出现时,它才会挂起。
当我直接在浏览器中加载 url 时,它会很好地显示 JSON 数据。即使我使用 Chrome 扩展 Postman 并手动将 Authorization
标头设置为与 jQuery 请求相同,它仍然可以正常加载数据(尽管我不认为 Postman 模拟跨域请求)。
知道为什么GET
请求仍处于待处理状态并且不返回任何错误或标头吗?
【问题讨论】:
【参考方案1】:不太确定问题出在哪里。看起来你遇到了某事。类似这样:cross-origin 'Authorization'-header with jquery.ajax()
另外,您是否更改了 Ember.SimpleAuth 代码中的任何内容?因为出于安全原因,默认情况下它不应该在跨域请求中包含令牌...
您可能还想查看 jQuery 中的这个已知问题:Sending credentials with cross-domain posts?,它也与跨域发送授权标头有关。
我将研究 Ember.SimpleAuth 在这种情况下可能如何提供帮助。
【讨论】:
这很奇怪,因为如果我刷新它似乎可以工作,所以我确实在OPTIONS
请求之后返回了正确的标题。我没有更改SimpleAuth
代码 - 我确实注意到if (!jqXHR.crossDomain && !Ember.isEmpty(session.get('authToken')))
行但jqXHR
对象不包含crossDomain
属性...我实际上发现跨域属性在options
目的。可能是错误或系统差异?我通过将REST
服务器更改为同一个域来暂时解决了这种情况。我不认为这是一个SimpleAuth
问题,也许是一个错误......我不确定。
我也尝试在发送Authorization
标头之前添加jqXHR.withCredentials = true;
,但这并不能解决问题。【参考方案2】:
我做了一些调查:通常 Ember.SimpleAuth 应该与 CORS 一起使用。我认为你缺少的是
Access-Control-Allow-Origin: http://subdomain2.domain.com
GET 请求响应中的标头。另请参阅 Mozilla 文档中的示例:https://developer.mozilla.org/en-US/docs/HTTP/Access_control_CORS。每个响应都必须包含 Access-Control-Allow-Origin 标头。
HTH
【讨论】:
感谢您的检查。从上面的问题$headers->set('Access-Control-Allow-Origin', 'http://subdomain2.domain.com');
中可以看出,我肯定会返回此值,并且当我快速刷新时它会起作用,因此它绝对不会阻止跨域请求。也许这是我系统某处的错误,我会做更多的探索。
hm,看起来您在 OPTIONS 请求的响应中只有标头,而不是 GET。您还看到日志中的任何内容吗?
啊,GET 和 OPTIONS 都没有。如果我没有 GET 请求,则任何请求都不会起作用。看起来很奇怪。以上是关于HTTP标头设置授权标头阻止数据加载的主要内容,如果未能解决你的问题,请参考以下文章
有没有办法阻止 avplayer 发送范围 http 标头字段
被 CORS 阻止:预检响应中的 Access-Control-Allow-Headers 不允许请求标头字段授权