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

我有Rails 2.3.8,Ruby 1.8.7,Mongrel Web Server和MySQL数据库。

我处于开发模式 ,我需要find真正的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'] 

据我所见,没有获取本地机器远程地址的标准方法。 如果您需要远程地址(testing)您的地理编码,我build议将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 

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

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

所以,如果你在本地testing,那么你将会体验到127.0.0.1。 如果你通过你的本地networking发送它,它将成为你networking中的IP。 例如,我的办公室networking中的机器的IP是192.168.1.7,如果我通过同一networking中的另一台计算机(例如从192.168.1.13)访问我的应用程序在3000端口,那么我得到request.remote_ip为192.168.1.13

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

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

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

取决于你如何访问url。

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

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

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

我正在与Rspec进行testing,我所做的是:

 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 

它的function就像一个魅力! :)

问题:

我们最近试图为一个项目做类似的事情,并且在我们的代码中使用request.remote_ip时遇到了麻烦。 它一直返回127.0.0.1::1 。 当与Geocodergem相结合,它给了我们一个空arrays,基本上是无用的。

解:

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

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

这不是最好的办法,但我认为这是一个很好的解决scheme,因为它可以在本地和生产环境中使用。 唯一的潜在问题是如果你达到他们的API限制,但是对于小项目来说,这应该是一个没有问题的问题。