Rails - 如何获取访问者的IP地址?

20

我需要将访问者的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

我原以为问题只出现在我的电脑上,但我把链接发给了三个朋友,他们都看到了相同的 IP 地址:127.0.0.1

我已经花了一整天时间来解决这个问题,但还没有成功。

谢谢


也许你的应用程序被放置在反向代理之后了? - m_x
当“访问者”访问您的服务器时,该如何处理?当您使用EC2实例时,如何将请求发送到服务器? - Makis Tsantekidis
简单来说,我在浏览器中打开了我的网站并重新加载了页面,因为我想看到更改后的IP地址 - 但仍然是本地主机上的相同IP地址 - 127.0.0.1。 - user984621
1
@Afsane.F 你可以尝试开一个新的问题,并提供尽可能多的细节。缩小问题范围并提供更多的细节和数据可能会有所帮助。 - Tom
3个回答

24

当您访问本地站点时,您使用的是本地IP地址,即127.0.0.1。

您正在正确地查看访问者的IP地址,并且您所看到的结果是符合预期的。

您想要使用

@ip = request.remote_ip

因为这将考虑到大多数反向代理和其他你可能遇到的情况,其中request.env ['REMOTE_ADDR']可能为空或本地代理的地址。

如果你确实在应用服务器前面有一个反向代理(你很可能有),你需要确保它在转发请求时设置了适当的头部信息。至少应该设置X-Forwarded-For头部信息

示例nginx配置

如果你正在使用nginx作为Rails应用程序的反向代理(即使用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 - user984621
很难说,没有了解你的设置。最有可能的情况是你正在访问某个代理服务器,该服务器将请求转发到你使用的Rails服务(如Unicorn、Thin、Webrick)。这个代理服务器是与你的应用程序本地相关的,如果它没有设置预期的头部信息,request.remote_ip 将无法获取到原始IP地址。 - Jakob S
如果有帮助的话,我正在使用Unicorn。 (我不知道代理) - user984621
那么你是直接访问Unicorn进程吗?你没有使用Apache或Nginx吗?或者可能使用了一些Amazon负载均衡器? - Jakob S
1
如果你在Rails端使用request.remote_ip,那么你已经做得很对了。然而,nginx需要配置以转发实际的远程IP地址,我已经更新了我的答案并提供了详细信息。 - Jakob S
显示剩余2条评论

6

x-forwarded-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地址可能会出错。


0
请注意,如果您正在使用AWS的任何负载均衡器,则可能需要适当配置这些负载均衡器,以便将客户端IP转发给它们。
通常情况下,Stack Overflow不喜欢只有链接的答案,但在这种情况下,由于问题非常古老,我们没有细节来回答具体问题,并且由于AWS提供的负载均衡器类型和配置方式不断变化,我将只发布一个 AWS Knowledge Base instructions的链接,用于通过负载均衡器转发客户端IP地址。
如果您正在使用内容交付网络(CDN)传递数据,则可能会遇到类似问题,在这种情况下,您需要联系CDN提供商以获取说明。

@Jakob S 正确地解释了如何配置nginx以传递X-Forwarded-For头部,这是当前的事实上标准,但X-前缀意味着它在相关的HTTP规范下明确非标准化。最终,您可能想要支持Forwarded头部,该头部在RFC 7239中指定,但截至目前(2019年1月),它尚未被广泛采用,也没有必要因为缺乏广泛的支持而切换。


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