2010-10-08 16 views
36

Mam Rails 2.3.8, Ruby 1.8.7, Mongrel Web Server i bazę danych MySQL.Uzyskaj prawdziwy adres IP w lokalnym środowisku programistycznym Rails

jestem w trybie rozwoju i muszę znaleźć prawdziwego adresu IP

Gdy używam request.remote_ip otrzymuję IP jako 127.0.0.1

wiem, jestem coraz 127.0.0.1 bo rozwijam się na lokalnej maszynie .. ale czy istnieje sposób na uzyskanie prawdziwego adresu IP, nawet jeśli jestem na lokalnym komputerze?

Używam tych wymienionych poniżej w moim kontrolerze i wszystko, co dostaję, to 127.0.0.1 z wszystkimi w widoku.

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

To dlatego, że rozwijają się na lokalnym komputerze. Jeśli ten kod znajduje się na serwerze i uzyskujesz dostęp do strony od klienta, otrzymasz * prawdziwy * adres IP. – Mischa

+0

spróbuj przejść do serwera na "prawdziwym" adresie. Więc nie przejdź do 127.0.0.1, ale do "zewnętrznego IP". Nie zapomnij uruchomić serwera, aby słuchać również na tym adresie! – gavit

Odpowiedz

30

O ile widzę, nie ma standardowej metody uzyskania zdalnego adresu lokalnej maszyny. Jeśli potrzebujesz zdalnego adresu do (testowania) geokodowania, sugeruję dodanie 127.0.0.1 do tabeli bazy danych, która dopasowuje adresy IP do lokalizacji.

W ostateczności możesz również zakodować kod zdalnego adresu. Na przykład. tak:

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

Nie sądzę dostaniesz „prawdziwe IP” na localhost i powodem tego faktycznie leży w protokole TCP/IP.

Zdalny adres IP zależy od sieci, do której wysyłane jest żądanie. Ponieważ jest to część protokołu TCP/IP do wysyłania adresu IP podczas komunikacji, zawsze przekłada się na względny adres IP, który może zrozumieć komputer docelowy. Kiedy żądanie znajduje się w Twojej podsieci, jest to twój lokalny adres IP. Z chwilą, gdy telefon trafi do sieci za pośrednictwem usługodawcy, przyjmuje globalny adres IP, który można śledzić z powrotem do usługodawcy (uwaga: jest to dyskusyjne i zależy od konfiguracji sieci).

Więc jeśli testujesz lokalnie, będzie to 127.0.0.1, jakiego doświadczyłeś. Jeśli wysyłasz go przez sieć lokalną, będzie to Twój adres IP w tej sieci. Na przykład adres IP urządzenia w mojej sieci biurowej to 192.168.1.7, a jeśli uzyskam dostęp do aplikacji na porcie 3000 przez inny komputer w tej samej sieci, powiedzmy od 192.168.1.13, otrzymam request.remote_ip jako 192.168.1.13

Oznacza to, że gdy jesteś na localhost, 127.0.0.1 jest swoje prawdziwe IP. I podobnie w przykładzie, o którym wspomniałem, 192.168.1.13 jest prawdziwym adresem IP maszyny, która wysłała żądanie.

+0

, więc czy istnieje sposób na uzyskanie adresu IP komputera, który wysłał żądanie? w twoim przykładzie: 192.168.1.13 – ben

5

Zależy od sposobu uzyskania dostępu do adresu URL.

Jeśli uzyskasz dostęp do adresu URL za pomocą http://127.0.0.1/.... lub http://localhost/...., otrzymasz 127.0.0.1 jako zdalny adres IP. Jeśli korzystasz z sieci LAN, użyj http: // {lan-ip}/....

np. http://172.20.25.210/.......

1

Jeśli uzyskujesz dostęp do maszyny deweloperskiej z prawdziwym adresem IP, powinieneś otrzymać swoje prawdziwe IP, więc nie używaj localhost, ale używaj swojego prawdziwego adresu IP. Nie wszystkie routery zezwalają na dostęp LAN do komputera na zewnętrzny adres IP, który faktycznie znajduje się w tej sieci LAN, ale większość będzie.

+0

W takim przypadku musisz upewnić się, że serwer nasłuchuje na określonym interfejsie. Próbowałem tego jeden raz i serwer nasłuchiwał tylko na interfejsie pętli zwrotnej (127.0.0.1), więc moja aplikacja Railsowa nigdy nie otrzymała żądania. Słuchanie na "0.0.0.0" zamiast tego sprawiło, że lewę. –

1

Mam testowanie z RSpec i co zrobiłem było:

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 

I to działało jak urok! :)

1

Problem:

Staraliśmy się zrobić coś podobnego dla projektu niedawno i były problemy z używaniem request.remote_ip w naszym kodzie. Ciągle powracał 127.0.0.1 lub ::1. W połączeniu z klejnotem Geokodera dawał nam pustą tablicę i był praktycznie bezużyteczny.

Rozwiązanie:

Jest to naprawdę bardzo miłe w telize.com API, która zwraca adres IP, co ją uderza. Kod wdrożyliśmy wyglądał mniej więcej tak:

nie jest to najbardziej szyn-y sposób to zrobić, ale myślę, że jest to bardzo dobre rozwiązanie, ponieważ będzie ona działać lokalnie i na produkcji, jak również. Jedynym potencjalnym problemem jest przekroczenie limitu API, ale w przypadku małych projektów nie powinno to stanowić problemu.

6

To co zwykle zrobić w dzisiejszych czasach:

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

Spowoduje to zwrócenie rzeczywistego adresu IP twojej maszyny rozwojowej. – BSB

+0

Czy wiesz, czy ma dzienny limit? – 7urkm3n

Powiązane problemy