Ottieni un vero indirizzo IP nell’ambiente di sviluppo di Rails locale

Ho Rails 2.3.8, Ruby 1.8.7, Mongrel Web Server e database MySQL.

Sono in modalità sviluppo e ho bisogno di trovare l’indirizzo IP reale

Quando uso request.remote_ip sto ottenendo l’IP come 127.0.0.1

So che sto ottenendo 127.0.0.1 perché sto sviluppando sul computer locale .. ma c’è un modo per ottenere il vero indirizzo IP anche se sono sulla macchina locale?

Sto usando questi menzionati qui sotto nel mio controller e tutto ciò che ottengo è 127.0.0.1 con tutti loro nella vista.

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

Per quanto posso vedere, non esiste un metodo standard per ottenere l’indirizzo remoto della macchina locale. Se è necessario l’indirizzo remoto per (testare) la geocodifica, suggerisco di aggiungere 127.0.0.1 alla tabella del database che corrisponde agli indirizzi IP con posizioni.

Come ultima possibilità potresti anche codificare il tuo indirizzo remoto. Ad esempio in questo modo:

 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 

Non penso che otterrai il tuo ‘real-ip’ su localhost e la ragione di ciò risiede nel TCP / IP.

L’indirizzo IP remoto dipende dalla rete alla quale viene inviata la richiesta. Poiché fa parte del protocollo TCP / IP per inviare il proprio indirizzo IP durante la comunicazione, si traduce sempre in un indirizzo IP relativo che il computer di destinazione può comprendere. Quando la richiesta è nella substring, è il tuo IP locale. Nel momento in cui esce dalla rete attraverso il fornitore di servizi, assume un IP globale, che può essere rintracciato al fornitore di servizi (Nota: questo è discutibile e dipende dalla configurazione della rete).

Quindi, se stai testando localmente, sarebbe 127.0.0.1 come hai sperimentato. Se lo invii tramite la tua rete locale, sarà il tuo IP all’interno di quella rete. Ad esempio, l’IP della mia macchina nella rete dell’ufficio è 192.168.1.7 e se accedo alla mia app a 3000 porte attraverso un altro computer nella stessa rete, ad esempio da 192.168.1.13, ottengo la request.remote_ip come 192.168.1.13

Ciò significa che, mentre sei su localhost, 127.0.0.1 è il tuo vero IP. Allo stesso modo nell’esempio che ho citato, 192.168.1.13 è l’IP reale per la macchina che ha inviato la richiesta.

Questo è quello che normalmente faccio oggigiorno:

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

Dipende da come accedi all’URL.

Se si accede http://127.0.0.1/.... utilizzando http://127.0.0.1/.... o http://localhost/.... , si otterrà 127.0.0.1 come ip remoto. Se si è su una LAN, utilizzare http: // {lan-ip} / ….

ad esempio http://172.20.25.210/.......

Se accedi al computer di sviluppo con il tuo IP reale dovresti ottenere il tuo reale IP, quindi non usare localhost, ma usi il tuo IP reale. Non tutti i router consentiranno l’accesso LAN a una macchina a un indirizzo IP esterno che si trova effettivamente su quella LAN, ma la maggior parte lo farà.

Sto testando con Rspec e quello che ho fatto è stato:

 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 

E ha funzionato come un fascino! 🙂

Problema:

Stavamo cercando di fare una cosa simile per un progetto di recente e stavamo avendo problemi nell’utilizzare request.remote_ip nel nostro codice. Continuava a restituire 127.0.0.1 o ::1 . Quando combinato con la gem di Geocoder ci stava dando un array vuoto ed era praticamente inutile.

Soluzione:

C’è un’API davvero carina su telize.com che restituisce l’indirizzo IP di qualunque cosa lo colpisca. Il codice che abbiamo implementato assomigliava a questo:

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

Non è il modo più adatto per farlo, ma penso che sia una soluzione piuttosto buona poiché funzionerà localmente e anche in produzione. L’unico problema potenziale è se si raggiunge il limite delle API, ma per i progetti di piccole dimensioni questo dovrebbe essere un problema.