【问题标题】:Rails - how to obtain visitors' IP address?Rails - 如何获取访问者的 IP 地址?
【发布时间】:2013-10-11 11:39:15
【问题描述】:

我需要将访问者的 IP 地址存储到我们的数据库中,这是我尝试这样做的方式:

@ip = request.remote_ip
@ip = request.env['REMOTE_ADDR']

但在这两种情况下,@ip 变量都存储了值 127.0.0.1,即使我将应用程序部署到 Amazon EC2 实例也是如此。

当我检查 http://www.whatismyip.com/ 时,它显示我的 IP 为 109.175.XXX.X

那么,为什么ruby变量总是显示127.0.0.1地址呢?如何获取真实IP?


编辑: 以下是以下输出:

request.env['HTTP_X_FORWARDED_FOR'] => 
request.remote_ip => 127.0.0.1
request.env['REMOTE_ADDR'] => 127.0.0.1
request.ip => 127.0.0.1

我以为问题出在我这边,但我将链接发送给我的 3 个朋友,他们都看到相同的 IP,只是 127.0.0.1

我整天都在解决这个问题,但仍然没有成功。

谢谢

【问题讨论】:

  • 也许你的应用在reverse proxy后面?
  • “访问者”如何访问您的服务器?当您使用 EC2 实例时,如何将请求发送到服务器?
  • 简单地说,我已经在浏览器中打开了我的网站并重新加载了页面,因为我想在那里看到更改后的 IP - 但仍然与 localhost 上的相同 - 127.0.0.1
  • @Afsane.F 您可能会更幸运地打开一个新问题并提供尽可能多的细节。缩小问题范围并提供更多详细信息和数据会很有帮助。

标签: ruby-on-rails ruby request ip


【解决方案1】:

当您访问本地站点时,您来自本地 IP 地址,即 127.0.0.1。

您所做的是访问者IP地址的正确方法,并且您看到的结果与预期的一样。

你想用

@ip = request.remote_ip

因为这考虑了大多数反向代理情况以及您可能遇到的其他情况,其中request.env['REMOTE_ADDR'] 可能为 nil 或本地代理的地址。

如果您的应用程序服务器前确实有一个反向代理(并且您可能有),您需要确保它在转发请求时设置了正确的标头。至少应该设置X-Forwarded-For header

示例 nginx 配置

如果您在 Rails 应用程序前使用 nginx 作为反向代理(即使用proxy_pass),则需要对其进行配置以将正确的标头添加到它发送的请求中。在X-Forwarded-For 的情况下使用:

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

您可能还需要配置以下内容以让 nginx 转发请求的主机名和协议:

# enable this if you forward HTTPS traffic to Rails,
# this helps Rack set the proper URL scheme for doing redirects:
proxy_set_header X-Forwarded-Proto $scheme;

# pass the Host: header from the client right along so redirects
# can be set properly within the Rack application
proxy_set_header Host $http_host;

【讨论】:

  • 感谢您的回复。但说实话,我仍然不明白为什么我在 Amazon EC2 上收到 127.0.0.1。我还使用request.remote_ip 命令对其进行了测试。为什么 EC2 上的生产模式显示 127.0.0.1 而不是 109.175.XXX.X
  • 不知道你的设置,很难说。很可能您正在访问一些代理网络服务器,该服务器将请求转发到您通过(Unicorn、Thin、Webrick)为 Rails 提供服务的任何内容。该代理是您应用的本地代理,如果它没有设置预期的标头,remote_ip 将不会获取原始 IP。
  • 它有帮助,我在 Unicorn 上运行。 (我不知道代理)
  • 所以你是直接打独角兽进程?你那里没有 Apache 或 Nginx?或者也许是一些亚马逊负载均衡器?
  • 如果您在 Rails 端使用 request.remote_ip,那么您已经做得对了。但是,需要将 nginx 配置为转发实际的远程 IP 地址,我已经更新了我的答案,详细说明了这一点。
【解决方案2】:

x-转发-for。 x-forwarded-for (XFF) 是一个标准代理标头,它指示请求在从客户端流向服务器的过程中流经的 IP 地址。

在我的 nginx 服务器配置中,

proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;

我正在获取客户端远程 IP,如下所示,

request.env['HTTP_X_FORWARDED_FOR'] || request.remote_ip

注意:如果客户端位于代理后面,则可能是错误的 IP 地址。

【讨论】:

    【解决方案3】:

    使用命令获取客户端ip:

    request.remote_ip
    

    【讨论】:

      【解决方案4】:

      请注意,如果您将 AWS 与他们提供的任何负载均衡器一起使用,您可能必须适当地配置这些负载均衡器才能让它们转发客户端 IP。

      通常 Stack Overflow 不喜欢只是一个链接的答案,但在这种情况下,由于这个问题非常古老,我们没有详细回答具体问题,而且因为 AWS 提供的负载均衡器类型和配置它们的方式不断变化,我将发布一个指向 AWS Knowledge Base instructions 的链接,用于通过负载均衡器转发客户端 IP 地址。

      如果您使用内容交付网络 (CDN) 来交付数据,您可能会遇到类似的问题,在这种情况下,您需要联系您的 CDN 提供商以获取相关说明。

      @Jakob S correctly explains 如何配置nginx 以传递X-Forwarded-For 标头,这是当前事实上的 标准,但X- 前缀意味着它明确非相关 HTTP 规范下的标准。最终,您可能希望支持 Forwarded 标头,该标头在 RFC 7239 中指定,但截至目前(2019 年 1 月),它尚未被广泛采用,由于缺乏广泛支持,不值得切换。

      【讨论】:

        猜你喜欢
        • 2020-12-12
        • 1970-01-01
        • 1970-01-01
        • 2018-11-17
        • 1970-01-01
        • 1970-01-01
        • 2012-04-23
        • 1970-01-01
        • 2011-04-15
        相关资源
        最近更新 更多