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 不允许请求标头字段授权

为 AVURLAssets 设置 HTTP 标头字段

Google Cast:加载元数据错误并且不存在 Access-Control-Allow-Origin 标头

EventSource 中的 HTTP 授权标头(服务器发送事件)