预检和重定向的CORS请求:不允许。解决方法?

时间:2016-01-22 14:51:36

标签: http redirect cors preflight

我正在设计一个允许用户进行身份验证(使用令牌)并且包含同一域内重定向的API。现在,对于返回303的端点的未经身份验证的请求,

GET /documents/123  --> 303 redirect to `/documents/abc`
GET /documents/abc  --> 200

一切都很顺利。

让我们对发送Authorization标头的同一端点进行经过身份验证的请求。这使请求成为preflighted request,浏览器执行预检OPTIONS请求,即

OPTIONS /documents/123   --> 204 (everything okay, please proceed)
GET /documents/123       --> 303 redirect to `/documents/abc`

此时,浏览器产生

而不是GET实际资源/documents/abc
XMLHttpRequest cannot load http://localhost:8000/people/username/nschloe. 
The request was redirected to 'http://localhost:8000/people/YDHa-B2FhMie', 
which is disallowed for cross-origin requests that require preflight.

此行为符合the standard

  

7.1.5带预检的跨源请求

     

如果响应的HTTP状态代码不在2xx范围内

     

应用网络错误步骤。

这似乎意味着一个无法重定向经过身份验证的资源,即使重定向位于同一个域(localhost)。

这真的可以吗?有共同的解决方法吗?

1 个答案:

答案 0 :(得分:15)

原始标准确实排除了CORS预检成功后的重定向。 Quoting § 7.1.5.3

  

这是实际的请求。在提出请求时,应用make a request步骤并遵守下面的请求规则。

     
      
  • 如果响应的HTTP状态代码为301,302,303,307或308   应用缓存和网络错误步骤。
  •   

由于您的努力(谢谢!),8月4日标准为updated,以便在成功进行CORS预检检查后允许重定向。

在浏览器迎头赶上之前,唯一可行的选择似乎是一个或组合:

  1. 仅针对simple requests发布重定向。
  2. 发布305 redirect,在Location标题中将您自己的网址作为“代理”。准备好有限的浏览器支持,因为305已被弃用。
  3. 做一个虚假的“重定向”:
    • 使用meta refresh和/或Javascript Location更改返回HTML。
    • 返回具有视口填充iframe的HTML,并将重定向目标作为iframe的源。
    • 显示用户必须单击以访问内容的链接。