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

时间:2022-02-25 23:32:51

I have Rails 2.3.8, Ruby 1.8.7, Mongrel Web Server and MySQL database.

我有Rails 2.3.8、Ruby 1.8.7、Mongrel Web服务器和MySQL数据库。

I am in the development mode and I need to find the real IP address

我在开发模式,我需要找到真正的IP地址

When I use request.remote_ip I am getting the IP as 127.0.0.1

当我使用要求。我得到的IP是127.0.0.1。

I know I am getting 127.0.0.1 because I am developing on the local machine.. but is there a way to get the real ip-address even if I am on the local machine?

我知道我得到了127.0.0.1因为我在本地机器上开发但是,即使我在本地机器上,有没有办法获得真正的ip地址呢?

I am using these mentioned below in my controller and all I get is 127.0.0.1 with all of them in the view.

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

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

7 个解决方案

#1


30  

As far as I can see there is no standard method for getting the remote address of your local machine. If you need the remote address for (testing) your geocoding, I suggest adding 127.0.0.1 to your database table that matches IP addresses with locations.

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

As a last resort you could also hard code your remote address. E.g. like this:

最后,你也可以硬编码你的远程地址。例如,像这样:

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


15  

I don't think you will get your 'real-ip' on localhost and the reason for this actually lies in TCP/IP.

我认为您不会在本地主机上获得“real-ip”,原因实际上是TCP/IP。

The remote ip address depends upon the network the request is being sent to. Since it is a part of TCP/IP to send your IP address when communicating, it always translates to relative IP address that the destination computer may understand. When the request is within your subnet, it is your local IP. The moment it goes out to the network through your service provider, it assumes a global IP, which can be tracked back to the service provider (Note: this is arguable and depends on your network setup).

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

So if you are testing locally then it would be 127.0.0.1 as you have experienced. If you are sending it over your local network, it'll be your IP within that network. For example, my machine's IP in my office network is 192.168.1.7, and if I access my app at 3000 port through another computer in the same network, say from 192.168.1.13, then I get the request.remote_ip as 192.168.1.13

如果你在本地测试,那么它将是你经历过的127。0。1。如果你通过你的本地网络发送它,它将是你在那个网络中的IP。例如,我的计算机在我的office网络中的IP是192.168.1.7,如果我通过同一网络中的另一台计算机(比如192.168.1.13)在3000端口访问我的应用程序,那么我就会收到请求。remote_ip作为192.168.1.13

What this is means is, while you are on localhost, 127.0.0.1 is your real IP. And likewise in the example I mentioned, 192.168.1.13 is the real IP for the machine that sent the request.

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

#3


6  

This is what I normally do nowadays:

这是我现在通常的做法:

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

#4


5  

Depends on how you access the url.

取决于您如何访问url。

If you access the url using http://127.0.0.1/.... or http://localhost/.... , you'll get 127.0.0.1 as the remote ip. If you are on a LAN, use http://{lan-ip}/....

如果您使用http://127.0.0.1/…访问url。或http://localhost/...。,您将获得127.0.0.1作为远程ip。如果你是在一个局域网,使用http:// {局域网ip } / ....

for e.g. http://172.20.25.210/.......

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

#5


1  

If you access the development machine with your real IP you should get your real IP, so don't use localhost, but your use your real IP. Not all routers are will allow LAN access to a machine to an external IP address that is actually on that LAN, but most will.

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

#6


1  

I am testing with Rspec and what I did was:

我正在用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

And it worked like a charm! : )

它就像一种魅力!:)

#7


1  

Problem:

问题:

We were trying to do a similar thing for a project recently and were having trouble using request.remote_ip in our code. It kept returning 127.0.0.1 or ::1. When combined with the Geocoder gem it was giving us an empty array and was basically useless.

我们最近在一个项目中尝试做类似的事情,并且在使用请求时遇到了麻烦。remote_ip在我们的代码。它一直返回127.0.0.1或::1。当与Geocoder gem结合时,它给了我们一个空数组,基本上没用。

Solution:

解决方案:

There's a really nice API at telize.com which returns the IP address of whatever hits it. The code we implemented looked something like this:

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

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

位置= Geocoder.search(HTTParty.get(“http://www.telize.com/ip”).body)

It's not the most rails-y way to do it, but I think this is a pretty good solution since it will work locally and on production as well. The only potential problem is if you hit their API limit, but for small projects this should be a non-issue.

这不是最草率的方法,但我认为这是一个很好的解决方案,因为它将在本地和生产上都能工作。唯一可能的问题是,如果您达到了他们的API限制,但是对于小型项目来说,这应该不是问题。

#1


30  

As far as I can see there is no standard method for getting the remote address of your local machine. If you need the remote address for (testing) your geocoding, I suggest adding 127.0.0.1 to your database table that matches IP addresses with locations.

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

As a last resort you could also hard code your remote address. E.g. like this:

最后,你也可以硬编码你的远程地址。例如,像这样:

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


15  

I don't think you will get your 'real-ip' on localhost and the reason for this actually lies in TCP/IP.

我认为您不会在本地主机上获得“real-ip”,原因实际上是TCP/IP。

The remote ip address depends upon the network the request is being sent to. Since it is a part of TCP/IP to send your IP address when communicating, it always translates to relative IP address that the destination computer may understand. When the request is within your subnet, it is your local IP. The moment it goes out to the network through your service provider, it assumes a global IP, which can be tracked back to the service provider (Note: this is arguable and depends on your network setup).

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

So if you are testing locally then it would be 127.0.0.1 as you have experienced. If you are sending it over your local network, it'll be your IP within that network. For example, my machine's IP in my office network is 192.168.1.7, and if I access my app at 3000 port through another computer in the same network, say from 192.168.1.13, then I get the request.remote_ip as 192.168.1.13

如果你在本地测试,那么它将是你经历过的127。0。1。如果你通过你的本地网络发送它,它将是你在那个网络中的IP。例如,我的计算机在我的office网络中的IP是192.168.1.7,如果我通过同一网络中的另一台计算机(比如192.168.1.13)在3000端口访问我的应用程序,那么我就会收到请求。remote_ip作为192.168.1.13

What this is means is, while you are on localhost, 127.0.0.1 is your real IP. And likewise in the example I mentioned, 192.168.1.13 is the real IP for the machine that sent the request.

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

#3


6  

This is what I normally do nowadays:

这是我现在通常的做法:

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

#4


5  

Depends on how you access the url.

取决于您如何访问url。

If you access the url using http://127.0.0.1/.... or http://localhost/.... , you'll get 127.0.0.1 as the remote ip. If you are on a LAN, use http://{lan-ip}/....

如果您使用http://127.0.0.1/…访问url。或http://localhost/...。,您将获得127.0.0.1作为远程ip。如果你是在一个局域网,使用http:// {局域网ip } / ....

for e.g. http://172.20.25.210/.......

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

#5


1  

If you access the development machine with your real IP you should get your real IP, so don't use localhost, but your use your real IP. Not all routers are will allow LAN access to a machine to an external IP address that is actually on that LAN, but most will.

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

#6


1  

I am testing with Rspec and what I did was:

我正在用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

And it worked like a charm! : )

它就像一种魅力!:)

#7


1  

Problem:

问题:

We were trying to do a similar thing for a project recently and were having trouble using request.remote_ip in our code. It kept returning 127.0.0.1 or ::1. When combined with the Geocoder gem it was giving us an empty array and was basically useless.

我们最近在一个项目中尝试做类似的事情,并且在使用请求时遇到了麻烦。remote_ip在我们的代码。它一直返回127.0.0.1或::1。当与Geocoder gem结合时,它给了我们一个空数组,基本上没用。

Solution:

解决方案:

There's a really nice API at telize.com which returns the IP address of whatever hits it. The code we implemented looked something like this:

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

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

位置= Geocoder.search(HTTParty.get(“http://www.telize.com/ip”).body)

It's not the most rails-y way to do it, but I think this is a pretty good solution since it will work locally and on production as well. The only potential problem is if you hit their API limit, but for small projects this should be a non-issue.

这不是最草率的方法,但我认为这是一个很好的解决方案,因为它将在本地和生产上都能工作。唯一可能的问题是,如果您达到了他们的API限制,但是对于小型项目来说,这应该不是问题。