2010-10-08 17 views
36

Ho Rails 2.3.8, Ruby 1.8.7, Mongrel Web Server e database MySQL.Ottieni un indirizzo IP reale nell'ambiente di sviluppo Rails locale

Sono in modalità sviluppo e ho bisogno di trovare il vero indirizzo IP

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

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

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

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

Questo perché si sta sviluppando sul computer locale. Se questo codice si trova su un server e si accede alla pagina da un client, si otterrebbe l'indirizzo * reale * IP. – Mischa

+0

prova ad andare al server sul tuo indirizzo "reale". Quindi non andare su 127.0.0.1, ma sul tuo 'ip esterno'. Non dimenticare di eseguire il server per ascoltare anche su quell'indirizzo! – gavit

risposta

30

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 risorsa, è possibile anche codificare il proprio indirizzo remoto. Per 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 
15

Non penso che otterrete il vostro 'real-ip' su localhost e la ragione di ciò si trova in realtà in 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 sottorete, è 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 si esegue il test localmente, sarebbe 127.0.0.1 come si è verificato. 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 si è su localhost, 127.0.0.1 è il proprio IP reale. Allo stesso modo nell'esempio che ho citato, 192.168.1.13 è l'IP reale per la macchina che ha inviato la richiesta.

+0

quindi c'è un modo per ottenere l'indirizzo IP della macchina che ha inviato la richiesta? nel tuo esempio essere: 192.168.1.13 – ben

5

Dipende da come si accede all'URL.

Se si accede all'URL 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}/....

per es. http://172.20.25.210/.......

1

Se si accede al computer di sviluppo con il proprio IP reale, si dovrebbe ottenere il proprio IP reale, quindi non utilizzare localhost, ma si utilizza il proprio 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à.

+0

In tal caso devi assicurarti che il server sia in ascolto sull'interfaccia specifica. L'ho provato una volta e il server era in ascolto solo sull'interfaccia di loopback (127.0.0.1), quindi l'applicazione Rails non ha mai ricevuto la richiesta. Ascoltare su '0.0.0.0' invece ha funzionato. –

1

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! :)

1

Problema:

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

Soluzione:

C'è davvero una bella API a telize.com che restituisce l'indirizzo IP di qualsiasi colpisce. Il codice che abbiamo implementato sembrava qualcosa di simile:

Non è il modo più rotaie-y per farlo, ma penso che questo è un buon soluzione dal momento che lavorerà a livello locale e sulla produzione pure. L'unico problema potenziale è se si raggiunge il limite delle API, ma per i progetti di piccole dimensioni questo dovrebbe essere un problema.

6

Questo è quello che faccio di solito al giorno d'oggi:

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

Ciò restituirà l'IP reale della macchina di sviluppo – BSB

+0

Sai, ha un limite giornaliero? – 7urkm3n