浏览器不显示X-Forwarded-For头的原因

18

注意: 请确保阅读完整的问题

我试图理解为什么浏览器不会每次请求页面时显示X-Forwarded-For头信息

顺便说一下,这是我的请求头信息

Request URL:http://localhost:3000/users/sign_in
Request Method:GET
Status Code:304 Not Modified

请求标头:

Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en-GB,en-US;q=0.8,en;q=0.6
Cache-Control:max-age=0
Connection:keep-alive
Cookie:undefined=0; poasterapp=s%3A4faaa6b1723e7c6fbd949083532c52598652547b.sNX%2BKOEed2TEQkQN7I7K5lgpoHMRpwerKFvUegMnTVI; _minerva_session=BAh7CUkiD3Nlc3Npb25faWQGOgZFRkkiJWEyM2Q0ZTViMWEyODBiYmFmODEwZTJhZmUwNWU5ODk5BjsAVEkiE3VzZXJfcmV0dXJuX3RvBjsARiIGL0kiCmZsYXNoBjsARm86JUFjdGlvbkRpc3BhdGNoOjpGbGFzaDo6Rmxhc2hIYXNoCToKQHVzZWRvOghTZXQGOgpAaGFzaHsGOgphbGVydFQ6DEBjbG9zZWRGOg1AZmxhc2hlc3sGOwpJIgAGOwBUOglAbm93MEkiEF9jc3JmX3Rva2VuBjsARkkiMUN0Uk56SXU0dUdIdzgwcFZJM3R0L2N4dlovRllTSGRrQ2o1R0VVanhIaVk9BjsARg%3D%3D--6bd89ce9d29e9bdcf56573f9a153dc663a8fe755
Host:localhost:3000
If-None-Match:"785d34e3998360353567fc710af123fb"
User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.102 Safari/537.36

响应头(不需要,但仍然在这里)

Cache-Control:max-age=0, private, must-revalidate
Connection:close
ETag:"785d34e3998360353567fc710af123fb"
Server:thin 1.5.0 codename Knife
Set-Cookie:_minerva_session=BAh7CEkiD3Nlc3Npb25faWQGOgZFRkkiJWEyM2Q0ZTViMWEyODBiYmFmODEwZTJhZmUwNWU5ODk5BjsAVEkiE3VzZXJfcmV0dXJuX3RvBjsARiIGL0kiEF9jc3JmX3Rva2VuBjsARkkiMUN0Uk56SXU0dUdIdzgwcFZJM3R0L2N4dlovRllTSGRrQ2o1R0VVanhIaVk9BjsARg%3D%3D--dfb3ce9f5c97463cfcd0229a133654e6cc606d98; path=/; HttpOnly
X-Request-Id:41a6f3062dc8bc36b7b3eae71dc5075d
X-Runtime:89.238257
X-UA-Compatible:IE=Edge

现在如上所述,我在请求标头中没有看到任何 X-Forwarded-For

通过阅读X-Forwarded-For维基页面,让我感觉它是由缓存服务器完成的(在我的情况下,我相信是我的ISP提供商),因此我可以放心地认为,X-Forwarded-For标头是在缓存服务器端(ISP提供商)添加的。

如果,那么有一件事困扰着我

为什么同样的情况也适用于在我本地机器上运行的服务器以及我通过浏览器访问它们的方式,例如:http://localhost:3000

3个回答

15
X-Forwarded-For不是RFC 2616 Section 5.3中规定的标准请求头之一,该部分规定了协议标准请求头,它们是(如在RFC中所述):
  • Accept
  • Accept-Charset
  • Accept-Encoding
  • Accept-Language
  • Authorization
  • Expect
  • From
  • Host
  • If-Match
  • If-Modified-Since
  • If-None-Match
  • If-Range
  • If-Unmodified-Since
  • Max-Forwards
  • Proxy-Authorization
  • Range
  • Referer
  • TE
  • User-Agent
为使传入请求携带自定义[X-Forwarded-For]头,必须由调用客户端显式地将其添加到该请求中。没有看到该头信息最简单的解释是发送请求的客户端没有手动添加它。

棘手的问题在于,您期望看到的标题不一定是您应该期望收到的标题,除非您的服务与调用方之间存在合同,该合同与HTTProtocol不同,指示您应该在请求标头中指定X-Forwarded-For值。正如其他人已经指出的那样,XFF标头通常由代理服务器或负载均衡器设置,以指示真正的请求者是通过他们的代理操作的。

作为服务提供商,如果您要求在所有请求中设置[X-Forwarded-For]标头,则必须在服务策略级别上强制执行。如果您不想为不确定使用其代理IP屏蔽了谁的代理帐户提供服务,请使用403 Forbidden拒绝其请求。如果您处于必须处理这些请求但依赖于此标头设置的情况下,则必须想出一种自定义过程,以便您可以将其错误传达回去。

以下是HTTProtocol关于匿名性的说明:

由于链接的源可能是私人信息或可能会透露其他私人信息来源,因此强烈建议用户能够选择是否发送Referer字段。例如,浏览器客户端可以有一个切换开关,用于公开/匿名浏览,分别启用/禁用发送Referer和From信息。如果引用页面使用安全协议传输,则客户端在(非安全的)HTTP请求中不应包括Referer头字段。使用HTTP协议的服务的作者不应该使用基于GET的表单提交敏感数据,因为这将导致这些数据被编码在请求URI中。许多现有的服务器、代理和用户代理都会在某些地方记录请求URI,从而可能对第三方可见。服务器可以改用基于POST的表单提交。在每个请求中发送详细的用户定制接受标头字段,特别是如果这些标头字段包括质量值,服务器可以将其用作相对可靠且长期存在的用户标识符。这样的用户标识符将允许内容提供者进行点击跟踪,并允许协作内容提供者匹配单个用户的跨服务器点击跟踪或表单提交。请注意,在许多未经代理的用户中,运行用户代理的主机的网络地址也将用作长期存在的用户标识符。在使用代理增强隐私的环境中,用户代理应该在向最终用户提供接受标头配置选项时保守。作为极端隐私措施,代理可以过滤转发请求中的接受标头。提供高度标头可配置性的通用用户代理应该警告用户可能涉及的隐私损失。
个人而言,我会使用401.2拒绝请求,并通过WWW-Authenticate响应头将请求者路由到一个挑战屏幕,向他们展示通知,告知他们无法匿名访问您的网站。这是一种有点扭曲的使用WWW-Authenticate标头的方式,但似乎您希望X-Forwarded-For标头确认和识别真正的请求者,并允许公共非匿名访问您的服务。对我来说,这是一个身份验证问题。

6
为什么您期望在首次出现时看到 X-Forwarded-For?您正在连接到运行在 localhost 上的 Web 服务器,因此根本没有涉及 ISP 提供商。即使您通过 ISP 连接到 Web 服务器,也不太可能将 X-Forwarded-For 添加到请求中。通常是 HTTP 代理服务器或负载均衡器添加 X-Forwarded-For,而您并未经过任何一个。Web 浏览器永远不会包含 X-Forwarded-For

是的,我知道在localhost上运行不涉及ISP,但出于好奇,我想知道为什么我的本地应用服务器中的请求标头中会列出X-Forwarded-For?因为肯定没有负载均衡器参与,所以我唯一的假设是浏览器添加了它,这就是为什么我在问题中提到无法在Web检查工具中找到它的原因。 - Ratatouille
为什么本地浏览器连接本地Web服务器要涉及ISP呢?一切都在同一台PC上。它甚至不会产生网络流量,因为操作系统足够聪明,知道两个端点都是本地的,并将相应地路由数据包。至于标头,浏览器并没有创建它,正如您的检查工具所证明的那样。因此,它必须来自其他地方。无论是您的Web服务器在内部创建它,还是PC上的应用程序拦截连接并注入它,或者类似情况。 - Remy Lebeau

6
  • ISP提供商不会添加X-Forwarded-For。
  • X-Forwarded-For不是用于用户识别代理/负载均衡器后面的应用程序。
  • X-Forwarded-For是为代理/负载均衡器后面的应用程序识别用户而设计的。

例如: 您有一个 Web 应用程序(php、java 等)。 同时您也有一个 HTTP 服务器(Apache、nginx 等),那么:

  1. 用户向 HTTP 服务器发出请求。
  2. HTTP 服务器将请求重定向到 Web 应用程序,并将X-Forwarded-For设置为用户 IP。
  3. 您的 Web 应用程序知道它在 HTTP 服务器后面,因此将读取 X-Forwarded-For 作为用户 IP。

你的第二和第三个要点有些自以为是。X-Forwarded-For头仅旨在识别通过代理帐户进行操作的真实请求者。设置XFF头的意图有多种目的,其中之一是为了在外部调用中通过代理匿名化内部用途的帐户进行内部标识。另一个目的是通过识别请求头值中的真实请求者来防止自己的代理服务成为滥用者的HTTP匿名化器。 - K. Alan Bates

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接