Получить реальный IP-адрес в локальной среде разработки Rails - PullRequest
40 голосов
/ 08 октября 2010

У меня есть 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']

Ответы [ 8 ]

32 голосов
/ 08 октября 2010

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

Я не думаю, что вы получите ваш 'настоящий ip' на localhost, и причина этого на самом деле кроется в TCP / IP.

Удаленный IP-адрес зависит от сети, в которую отправляется запрос. Поскольку отправка вашего IP-адреса при обмене данными является частью TCP / 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

Это означает, что, пока вы находитесь на локальном хосте, 127.0.0.1 - это ваш реальный IP. И аналогично в упомянутом выше примере 192.168.1.13 - это реальный IP-адрес компьютера, отправившего запрос.

13 голосов
/ 09 февраля 2017

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

if Rails.env.production?
  request.remote_ip
else
  Net::HTTP.get(URI.parse('http://checkip.amazonaws.com/')).squish
end
5 голосов
/ 08 октября 2010

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

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

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

1 голос
/ 19 июня 2015

Проблема:

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

Решение:

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

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

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

1 голос
/ 05 мая 2012

Я тестирую с 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 голос
/ 04 января 2011

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

0 голосов
/ 22 февраля 2019

Я должен был сделать это:

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