J'ai Rails 2.3.8, Ruby 1.8.7, Mongrel Web Server et base de données MySQL).
Je suis en mode de développement et je dois trouver la vraie adresse IP
Lorsque j'utilise request.remote_ip
J'obtiens l'IP en tant que 127.0.0.1
Je sais que je reçois 127.0.0.1
parce que je développe sur la machine locale .. mais existe-t-il un moyen d'obtenir la vraie adresse IP même si je suis sur la machine locale?
J'utilise ceux mentionnés ci-dessous dans mon contrôleur et tout ce que je reçois est 127.0.0.1
avec tous dans la vue.
request.remote_ip
request.env["HTTP_X_FORWARDED_FOR"]
request.remote_addr
request.env['REMOTE_ADDR']
Pour autant que je sache, il n'y a pas de méthode standard pour obtenir l'adresse distante de votre machine locale. Si vous avez besoin de l'adresse distante pour (tester) votre géocodage, je suggère d'ajouter 127.0.0.1 à votre table de base de données qui fait correspondre les adresses IP aux emplacements.
En dernier recours, vous pouvez également coder en dur votre adresse distante. Par exemple. comme ça:
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
Je ne pense pas que vous obtiendrez votre "real-ip" sur localhost et la raison en est en fait dans TCP/IP.
L'adresse IP distante dépend du réseau auquel la demande est envoyée. Puisqu'il fait partie de TCP/IP pour envoyer votre adresse IP lors de la communication, cela se traduit toujours par une adresse IP relative que l'ordinateur de destination peut comprendre. Lorsque la demande se trouve dans votre sous-réseau, il s'agit de votre adresse IP locale. Au moment où il sort sur le réseau via votre fournisseur de services, il suppose une adresse IP globale, qui peut être retracée au fournisseur de services (Remarque: cela est discutable et dépend de la configuration de votre réseau).
Donc, si vous testez localement, ce serait 127.0.0.1 comme vous l'avez vécu. Si vous l'envoyez sur votre réseau local, ce sera votre IP au sein de ce réseau. Par exemple, l'IP de ma machine dans mon réseau de bureau est 192.168.1.7, et si j'accède à mon application au port 3000 via un autre ordinateur du même réseau, disons depuis 192.168.1.13, alors j'obtiens le request.remote_ip comme 192.168.1.13
Cela signifie que, pendant que vous êtes sur localhost, 127.0.0.1 is votre véritable IP. Et de même dans l'exemple que j'ai mentionné, 192.168.1.13 est la véritable IP de la machine qui a envoyé la demande.
C'est ce que je fais normalement de nos jours:
if Rails.env.production?
request.remote_ip
else
Net::HTTP.get(URI.parse('http://checkip.amazonaws.com/')).squish
end
Dépend de la façon dont vous accédez à l'URL.
Si vous accédez à l'URL à l'aide de http://127.0.0.1/....
ou http://localhost/....
, tu auras 127.0.0.1
comme adresse IP distante. Si vous êtes sur un LAN, utilisez http: // {lan-ip}/....
par exemple http://172.20.25.210/.......
Je teste avec Rspec et ce que j'ai fait était:
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
Et ça a fonctionné comme un charme! :)
Si vous accédez à la machine de développement avec votre adresse IP réelle, vous devez obtenir votre adresse IP réelle, alors n'utilisez pas localhost, mais utilisez votre adresse IP réelle. Tous les routeurs ne permettent pas l'accès LAN à une machine à une adresse IP externe qui se trouve réellement sur ce LAN, mais la plupart le permettent.
Problème:
Nous essayions de faire une chose similaire pour un projet récemment et nous avions du mal à utiliser request.remote_ip
Dans notre code. Il a continué à renvoyer 127.0.0.1
Ou ::1
. Lorsqu'il était combiné avec la gemme Geocoder, il nous donnait un tableau vide et était essentiellement inutile.
Solution:
Il y a une API vraiment sympa sur telize.com qui retourne l'adresse IP de tout ce qui la frappe. Le code que nous avons implémenté ressemblait à ceci:
location = Geocoder.search(HTTParty.get('http://www.telize.com/ip').body)
Ce n'est pas la façon la plus Rails-y de le faire, mais je pense que c'est une assez bonne solution car elle fonctionnera localement et en production également. Le seul problème potentiel est que si vous atteignez leur limite d'API, mais pour les petits projets, cela ne devrait pas poser de problème.
Je devais faire ça:
require 'socket'
Socket.ip_address_list.detect(&:ipv4_private?)&.ip_address