【问题标题】:What is the correct way to render absolute URLs behind a reverse proxy?在反向代理后面呈现绝对 URL 的正确方法是什么?
【发布时间】:2020-02-22 08:36:46
【问题描述】:

我有一个 Web 应用程序在同一台服务器(myserver.example:80)上的反向代理后面的服务器(假设在 localhost:8000)上运行。由于反向代理的工作方式,应用程序会看到针对localhost:8000 的传入请求,因此我使用的框架会尝试生成看起来像localhost:8000/some/ressource 而不是myserver.example/some/ressource 的绝对URL。

从这样的代理服务器后面生成绝对 URL(即确定要使用的主机名)的“正确方法”是什么?特定的代理服务器、框架和语言无关紧要,我的意思更多的是 HTTP 意义上的。


根据我最初的研究:

  • RFC7230 explicitly says 代理必须在传递请求时更改 Host 标头以使其看起来像请求来自它们,因此看起来像使用 Host 来确定用于 URL 的主机名,但在大多数情况下在我看过的地方,一般建议似乎是配置您的反向代理,以便在传递请求时不更改 Host 标头(与规范相反)。
  • RFC7230 also says “请求 URI 重建”应使用以下字段来查找要使用的“授权组件”,尽管这似乎也仅适用于发出该请求的代理的角度,例如代理:
  • 修复了来自服务器或出站网关配置的 URI 授权组件
  • 如果是完整的 URI 而不是路径,则来自请求的第一行的权限组件
  • Host 标头(如果存在且不为空)
  • 侦听地址或主机名,以及传入端口号(如果它不是协议的默认端口号)
  • HTTP 1.0 根本没有 Host 标头,并且该标头是出于路由目的而添加的,而不是用于 URL 权限解析。
  • 有一些头是专门为让代理在路由后发送Host的旧值而设计的,例如ViaForwarded和非官方的X-Forwarded-Host,一些服务器和框架会检查,但是不是全部,考虑到其中有 3 个,甚至不清楚哪一个应该优先。

编辑:我也不知道 HTTPS 在这方面的工作方式是否有所不同,因为标头是加密有效负载的一部分和routing has to be performed another way because of this

【问题讨论】:

    标签: http http-headers reverse-proxy


    【解决方案1】:

    一般来说,我发现最好在应用程序中明确设置真实的主机和端口,而不是尝试从传入的请求中猜测这些。

    例如Jira allows you to set the Base URL through which Jira will be accessed(可能与实际运行的不同)。这意味着您可以在端口 8080 上运行 Jira,并在端口 80 和 443 上运行 Apache 或 Nginx(在相同甚至不同的服务器上)。

    【讨论】:

    • 我想这会节省大量的标头解析和猜测来简单地从配置中获取 URL 权限,并且 RFC7230 确实说你应该尝试使用这种环境数据,如果它可用的话。虽然我仍然想知道如果配置数据不是一个选项,是否有一种“正确”的方法可以从标题中找出这一点。
    • 我同意这个答案。负载均衡器将设置您可以解析的各种额外 HTTP 标头,但通常这是一场噩梦,并且不适用于不同的负载均衡器(例如,AWS ELB 和 Apache mod_proxy 设置不同的标头;另外,您可能仍想测试您的没有任何负载平衡器的本地软件)。我在这里写得更详细:databasesandlife.com/absolute-links
    猜你喜欢
    • 2014-03-22
    • 2021-03-18
    • 2017-10-28
    • 2022-11-10
    • 2019-04-25
    • 1970-01-01
    • 1970-01-01
    • 2011-09-23
    • 2017-02-05
    相关资源
    最近更新 更多