簡體   English   中英

在本地Rails開發環境中獲取真實的IP地址

[英]Get real IP address in local Rails development environment

我有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']

據我所知,沒有標准的方法來獲取本地機器的遠程地址。 如果您需要遠程地址(測試)地理編碼,我建議將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

我不認為你會在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

這意味着,當您使用localhost時,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

取決於您如何訪問網址。

如果您使用http://127.0.0.1/....http://localhost/....訪問該URL,您將獲得127.0.0.1作為遠程IP。 如果您在局域網上,請使用http:// {lan-ip} / ....

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

我正在測試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

它就像一個魅力! :)

問題:

我們最近試圖為一個項目做類似的事情,並且在我們的代碼中使用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限制,但對於小項目,這應該是一個非問題。

如果您使用真實IP訪問開發計算機,您應該獲得真正的IP,因此不要使用localhost,而是使用真正的IP。 並非所有路由器都允許LAN訪問機器到實際在該LAN上的外部IP地址,但大多數路由器都會。

我不得不這樣做:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM