在本地 Rails 开发环境中获取真实 IP 地址

Posted

技术标签:

【中文标题】在本地 Rails 开发环境中获取真实 IP 地址【英文标题】:Get real IP address in local Rails development environment 【发布时间】:2011-04-22 17:21:57 【问题描述】:

我有 Rails 2.3.8、Ruby 1.8.7、Mongrel Web Server 和 mysql 数据库。

我处于开发模式,我需要找到真实的IP地址

当我使用 request.remote_ip 时,我得到的 IP 为 127.0.0.1

我知道我收到了127.0.0.1,因为我正在本地机器上开发.. 但是即使我在本地机器上,有没有办法获取真实的 IP 地址?

我在我的控制器中使用下面提到的这些,我得到的只是127.0.0.1,它们都在视图中。

request.remote_ip
request.env["HTTP_X_FORWARDED_FOR"]
request.remote_addr
request.env['REMOTE_ADDR']

【问题讨论】:

这是因为你是在本地机器上开发的。如果此代码在服务器上,并且您从客户端访问该页面,您将获得 真实 IP 地址。 尝试使用您的“真实”地址访问服务器。所以不要去 127.0.0.1,而是去你的“外部 ip”。不要忘记运行服务器来监听该地址! 【参考方案1】:

据我所知,没有获取本地计算机远程地址的标准方法。如果您需要远程地址来(测试)您的地理编码,我建议将 127.0.0.1 添加到您的数据库表中,以匹配 IP 地址和位置。

作为最后的手段,您还可以硬编码您的远程地址。例如。像这样:

class ApplicationController < ActionController::Base
  def remote_ip
    if request.remote_ip == '127.0.0.1'
      # Hard coded remote address
      '123.45.67.89'
    else
      request.remote_ip
    end
  end
end

class MyController < ApplicationController
  def index
    @client_ip = remote_ip()
  end
end

【讨论】:

【参考方案2】:

我认为您不会在 localhost 上获得您的“真实 IP”,其原因实际上在于 TCP/IP。

远程 IP 地址取决于请求发送到的网络。由于在通信时发送您的 IP 地址是 TCP/IP 的一部分,因此它总是转换为目标计算机可以理解的相对 IP 地址。当请求在您的子网内时,它是您的本地 IP。当它通过您的服务提供商进入网络时,它假定一个全球 IP,可以追溯到服务提供商(注意:这是有争议的,取决于您的网络设置)。

因此,如果您在本地进行测试,那么正如您所经历的那样,它将是 127.0.0.1。如果您通过本地网络发送它,它将是您在该网络中的 IP。例如,我的机器在我的办公网络中的 IP 是 192.168.1.7,如果我通过同一网络中的另一台计算机在 3000 端口访问我的应用程序,比如从 192.168.1.13,那么我得到 request.remote_ip 为 192.168.1.13

这意味着,当你在本地主机上时,127.0.0.1 你的真实 IP。同样在我提到的示例中,192.168.1.13 是发送请求的机器的真实 IP。

【讨论】:

那么有没有办法获取发送请求的机器的 IP 地址?在您的示例中为:192.168.1.13【参考方案3】:

取决于您访问网址的方式。

如果您使用 http://127.0.0.1/....http://localhost/.... 访问网址,您将获得 127.0.0.1 作为远程 IP。如果您在 LAN 上,请使用 http://lan-ip/....

例如http://172.20.25.210/.......

【讨论】:

【参考方案4】:

如果你用你的真实IP访问开发机器,你应该得到你的真实IP,所以不要使用localhost,而是使用你的真实IP。并非所有路由器都允许 LAN 访问实际位于该 LAN 上的外部 IP 地址的机器,但大多数都允许。

【讨论】:

在这种情况下,您必须确保服务器侦听特定接口。我试过一次,服务器只监听环回接口(127.0.0.1),所以我的 Rails 应用程序从未收到请求。收听0.0.0.0 就成功了。【参考方案5】:

我正在使用 Rspec 进行测试,我所做的是:

request.stub(:remote_ip).and_return('198.172.43.34')
Instance.stub(:find_by_key).and_return(@instance)
before = @instance.weekly_statistic.times_opened_by['198.172.43.34']

get :key, :key=>"314C00"

@instance.weekly_statistic.times_opened_by['198.172.43.34'].should == before+1

它就像一个魅力! :)

【讨论】:

【参考方案6】:

问题:

我们最近试图为一个项目做类似的事情,但在我们的代码中使用 request.remote_ip 时遇到了问题。它不断返回127.0.0.1::1。当与 Geocoder gem 结合使用时,它给了我们一个空数组,基本上没有用。

解决方案:

telize.com 有一个非常好的 API,它返回任何命中它的 IP 地址。我们实现的代码如下所示:

location = Geocoder.search(HTTParty.get('http://www.telize.com/ip').body)

这不是最符合标准的方法,但我认为这是一个非常好的解决方案,因为它可以在本地和生产环境中使用。唯一的潜在问题是,如果您达到了他们的 API 限制,但对于小型项目,这应该不是问题。

【讨论】:

仅供参考:Telize 在该端点关闭了他们的公共服务。 cambus.net/adventures-in-running-a-free-public-api【参考方案7】:

这是我现在通常做的:

if Rails.env.production?
  request.remote_ip
else
  Net::HTTP.get(URI.parse('http://checkip.amazonaws.com/')).squish
end

【讨论】:

这会返回你开发机器的真实IP 你知道吗,有涨停吗?【参考方案8】:

我必须这样做:

require 'socket'
Socket.ip_address_list.detect(&:ipv4_private?)&.ip_address

【讨论】:

【参考方案9】:

您可以使用request.ip 来获取您的真实机器IP,尽管request.remote_ip 在您想要其他机器的IP 时可能会更好。

【讨论】:

以上是关于在本地 Rails 开发环境中获取真实 IP 地址的主要内容,如果未能解决你的问题,请参考以下文章

获取本地请求的真实IP地址

使用Fav-up工具获取目标服务器的真实IP地址

java如何获取用户真实的ip

如何设定虚拟机器和本地电脑的IP不相同?

java中,如何获取真实的IP地址?

CuteKe网站开发与安全5——真实IP地址与一次惨痛的经历