2010-10-08 112 views
36

我有Rails 2.3.8,Ruby 1.8.7,Mongrel Web Server和MySQL数据库。获取本地Rails开发环境中的真实IP地址

我在发展模式,我需要找到真正的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'] 
+0

这是因为你在本地机器上开发。如果此代码位于服务器上,并且您从客户端访问该页面,则将获得*真实* IP地址。 – Mischa 2010-10-08 05:36:24

+0

尝试去你的'真实'的地址上的服务器。所以不要去127.0.0.1,而是去你的'外部IP'。不要忘记运行服务器以侦听该地址! – gavit 2015-12-05 12:09:27

回答

30

据我所见,没有用于获取本地计算机远程地址的标准方法。如果您需要远程地址(测试)您的地理编码,我建议将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 
15

我不认为你会得到你的'真正的IP'在本地主机,其原因实际上在于TCP/IP。

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

所以,如果你在本地测试,那么它会是你所经历的127.0.0.1。如果您通过本地网络发送它,它将成为您网络中的IP。例如,我的办公室网络中的计算机IP为192.168.1.7,如果我通过同一网络中的另一台计算机(例如从192.168.1.13)访问3000端口的应用程序,那么我将request.remote_ip设为192.168.1.13

这是什么意思是,当你在本地主机上,127.0.0.1 你的真实IP。同样在我提到的例子中,192.168.1.13是发送请求的机器的真实IP。

+0

那么有没有办法获得发送请求的机器的IP地址?在你的例子中是:192.168.1.13 – ben 2015-01-05 16:07:17

5

取决于您如何访问网址。

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

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

1

如果您使用真实IP访问开发机器,您应该获得真实IP,因此不要使用localhost,而是使用您的真实IP。并不是所有的路由器都允许局域网访问一台机器到一个外部IP地址,而这个IP地址实际上是在这个局域网上,但大部分路由器都可以。

+0

在这种情况下,你必须确保服务器监听特定的接口。我尝试过这一次,服务器只监听回送接口(127.0.0.1),所以我的Rails应用程序从未收到请求。聆听'0.0.0.0'而不是诀窍。 – 2012-10-01 11:11:32

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 

和它的工作就像一个魅力! :)

1

问题:

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

解决方案:

有在telize.com一个非常好的API返回的任何撞击它的IP地址。我们实现的代码看起来是这样的:

这不是最导轨-Y方式做到这一点,但我觉得这是一个不错的解决方案,因为它会在本地和生产正常工作。唯一的潜在问题是如果你达到他们的API限制,但对于小型项目来说,这应该不是问题。

6

这就是我通常做时下:

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

这将返回您的开发机器的真实IP – BSB 2017-02-09 17:06:32

+0

你知道吗,它有每日限制吗? – 7urkm3n 2018-01-15 00:51:34