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

时间:2010-10-08 05:31:20

标签: ruby-on-rails ip-address geocoding

我有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-address?

我在我的控制器中使用了下面提到的这些内容,我得到的只是127.0.0.1,其中所有这些都在视图中。

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

9 个答案:

答案 0 :(得分:32)

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

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

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

答案 1 :(得分:15)

我认为你不会在localhost上获得'real-ip',其原因实际上在于TCP / IP。

远程IP地址取决于发送请求的网络。由于它是TCP / IP的一部分,在通信时发送您的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 < / p>

这意味着,当您使用localhost时,127.0.0.1 是您的真实IP。同样在我提到的示例中,192.168.1.13是发送请求的机器的真实IP。

答案 2 :(得分:13)

这就是我现在通常做的事情:

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

答案 3 :(得分:5)

取决于您如何访问网址。

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

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

答案 4 :(得分:1)

如果您使用真实IP访问开发计算机,您应该获得真正的IP,因此不要使用localhost,而是使用您的真实IP。并非所有路由器都允许LAN访问机器到实际在该LAN上的外部IP地址,但大多数都会。

答案 5 :(得分:1)

我正在使用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 :(得分:1)

<强>问题:

我们最近试图为一个项目做类似的事情,并且在我们的代码中使用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限制,但对于小项目,这应该是一个非问题。

答案 7 :(得分:0)

我必须这样做:

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

答案 8 :(得分:0)

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