Получить реальный IP-адрес в локальной среде разработки Rails

У меня есть Rails 2.3.8, Ruby 1.8.7, веб-сервер Mongrel и база данных 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']

Ответ 1

Насколько я вижу, нет стандартного метода для получения удаленного адреса вашей локальной машины. Если вам нужен удаленный адрес для (вашего) геокодирования, я предлагаю добавить 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

Ответ 2

Я не думаю, что вы получите свой "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-адресом для машины, отправившей запрос.

Ответ 3

Это то, что я обычно делаю сейчас:

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

Ответ 4

Зависит от того, как вы получаете доступ к URL.

Если вы используете URL-адрес с помощью http://127.0.0.1/.... или http://localhost/...., вы получите 127.0.0.1 в качестве удаленного ip. Если вы находитесь в локальной сети, используйте http://{lan-ip}/....

например. http://172.20.25.210/.......

Ответ 5

Если вы получаете доступ к машине разработки с вашим реальным IP-адресом, вы должны получить свой реальный IP-адрес, поэтому не используйте localhost, но используете свой реальный IP-адрес. Не все маршрутизаторы позволят LAN-доступу к компьютеру к внешнему IP-адресу, который на самом деле находится в этой локальной сети, но большинство будет.

Ответ 6

Я тестирую 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

И это сработало как шарм!:)

Ответ 7

Проблема:

Мы пытались сделать подобную вещь для проекта недавно и испытывали проблемы с использованием request.remote_ip в нашем коде. Он продолжал возвращать 127.0.0.1 или ::1. В сочетании с камнем Geocoder он давал нам пустой массив и был в основном бесполезен.

Решение:

Там действительно хороший API на telize.com, который возвращает IP-адрес того, что его ударяет. Код, который мы реализовали, выглядел примерно так:

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

Это не самый рельсовый способ сделать это, но я думаю, что это довольно хорошее решение, так как оно будет работать как на местном уровне, так и на производстве. Единственная потенциальная проблема заключается в том, что если вы нажмете свой лимит API, но для небольших проектов это будет не проблема.