【问题标题】:How to properly setup nginx Access-Control-Allow-Origin into response header based on the Origin header from the request?如何根据请求中的 Origin 标头将 nginx Access-Control-Allow-Origin 正确设置为响应标头?
【发布时间】:2013-01-08 02:09:00
【问题描述】:

我正在寻找一个 nginx 配置设置,它将Access-Control-Allow-Origin 设置为Origin 中收到的值。

似乎* 方法不适用于 Chrome,并且多个 URL 不适用于 Firefox,因为 CORS 规范不允许这样做。

到目前为止,唯一的解决方案是将Access-Control-Allow-Origin 设置为在源中收到的值(是的,可以实施一些验证)。

问题是如何在 nginx 中做到这一点,最好不安装额外的扩展。

set $allow_origin "https://example.com"
# instead I want to get the value from Origin request header
add_header 'Access-Control-Allow-Origin' $allow_origin;

【问题讨论】:

  • Chrome 绝对应该与Access-Control-Allow-Origin: * 一起使用。您能否提供一个失败的请求/响应标头的示例?这也可能有所帮助:gist.github.com/4165271
  • 是的,def 在带有 * 的 Chrome 中工作,我们已经使用了一段时间 - 这里是我的配置链接 distinctplace.com/2017/04/17/…

标签: nginx cors


【解决方案1】:

我自己开始使用它,这是我当前 Nginx 配置中的一行:

add_header 'Access-Control-Allow-Origin' "$http_origin";

这会设置一个标头以允许请求的来源作为唯一允许的来源。因此,无论您来自哪里,都是唯一允许的地方。所以它应该与允许“*”没有太大区别,但从浏览器的角度来看它看起来更具体。

此外,您可以在 Nginx 配置中使用条件逻辑来指定允许的主机名白名单。这是来自https://gist.github.com/Ry4an/6195025的示例

if ($http_origin ~* (whitelist\.address\.one|whitelist\.address\.two)$) {
  add_header Access-Control-Allow-Origin "$http_origin";
}

我计划在我自己的服务器上尝试这种技术,以将允许的域列入白名单。

【讨论】:

  • 如果您在多个主机上有需要访问 CORS 资源的页面,如果您不使用 *.通过指定来源,您将缓存中的资源锁定到请求它的第一页。来自其他页面的后续请求将访问允许错误来源的缓存页面。即使您的白名单允许它们,它们也将无法加载。 stackoverflow.com/questions/21104810/…
  • @Mnebuerquo 可以通过在cache_key 中添加$http_origin 来解决缓存问题。发送 Vary: Origin 标头应该负责客户端缓存。 (虽然 Ie/edge 似乎对 Vary 标头有问题)
【解决方案2】:

使用if 有时会破坏其他配置,例如try_files。您最终可能会遇到意外的 404。

Use map instead

map $http_origin $cors_header {
    default "";
    "~^https?://[^/]+\.example\.com(:[0-9]+)?$" "$http_origin";
}

server {
    ...
    location / {
        add_header Access-Control-Allow-Origin $cors_header;
        try_files $uri $uri/ /index.php;
    }
    ...
 }

If is evil

【讨论】:

  • $http_origin 在我的情况下似乎是空的,有什么想法吗?
  • @Toskan 请求来自哪里?如果您按照 CORS XHR 请求的推荐步骤操作,大多数现代浏览器都会设置 Origin 标头。但是如果你使用 curl 或者只是导航到一个网页,我不认为 Origin 标头是由浏览器设置的。
  • @phylae 实际上我误解了整点。我想我可以设置一个 http 请求标头服务于我的主页,从而允许访问第三方。例如。你去 myhomepage.com,我服务器 CORS 标头允许访问 someexternalapi.com。但当我终于看到它的另一种方式。 someexternalapi.com 需要服务器该标头。
  • YESSSSSSS 终于
【解决方案3】:

这是来自 conf.f 目录的文件的一部分,人们总是在其中描述他们的 Nginx 虚拟主机。 $http_origin 与 allowed_origins 列表进行比较,然后在第二个映射块中,系统根据允许的列表决定将什么写入“header Access-Control-Allow-Origin”。 这是部分代码。

#cat /etc/nginx/conf.d/somehost.conf

map $http_origin $origin_allowed {
        default 0;
        https://xxxx.yyyy.com 1;
        https://zzz.yyyy.com 1;
}
map $origin_allowed $origin {
        default "";
        1 $http_origin;
}
    
server {
       server_name somehost.com;
    #...[skipped text]
    add_header Access-Control-Allow-Origin $origin always;
    #....[skipped text]
}

我在我的服务器上测试它。一切正常。 祝你有美好的一天,身体健康, 尤金。

【讨论】:

  • 正如目前所写,您的答案尚不清楚。请edit 添加其他详细信息,以帮助其他人了解这如何解决所提出的问题。你可以找到更多关于如何写好答案的信息in the help center
  • 请提供更多关于如何使用它的上下文。我建议你阅读How to Answer
猜你喜欢
  • 2020-09-21
  • 2021-09-02
  • 1970-01-01
  • 2018-09-19
  • 1970-01-01
  • 2023-01-13
  • 2016-07-21
  • 2016-01-11
  • 1970-01-01
相关资源
最近更新 更多