Rails 2.3.8、Ruby 1.8.7、Mongrel Web Server and MySQL database。
私は開発モードで、実際の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']
私の知る限り、ローカルマシンのリモートアドレスを取得する標準的な方法はありません。ジオコーディング(テスト)にリモートアドレスが必要な場合は、IPアドレスと場所を一致させるデータベーステーブルに127.0.0.1を追加することをお勧めします。
最後の手段として、リモートアドレスをハードコーディングすることもできます。例えば。このような:
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
Localhostで「real-ip」を取得することはないと思いますが、その理由は実際にはTCP/IPにあります。
リモートIPアドレスは、要求の送信先のネットワークによって異なります。通信時にIPアドレスを送信することはTCP/IPの一部であるため、宛先コンピューターが理解できる相対IPアドレスに常に変換されます。要求がサブネット内にある場合、それはローカルIPです。サービスプロバイダーを介してネットワークに送信されると、グローバルIPが想定されます。これは、サービスプロバイダーに追跡できます(注:これは議論の余地があり、ネットワークの設定によって異なります)。
したがって、ローカルでテストしている場合、経験したとおり127.0.0.1になります。ローカルネットワーク経由で送信する場合、そのネットワーク内のIPになります。たとえば、オフィスネットワーク内のマシンのIPは192.168.1.7であり、同じネットワーク内の別のコンピューター、たとえば192.168.1.13から3000ポートでアプリにアクセスすると、request.remote_ipが192.168.1.13として取得されます
これが意味するのは、ローカルホストにいる間、127.0.0.1 is実際のIPです。同様に、前述の例では、192.168.1.13は要求を送信したマシンの実際のIPです。
これは最近私が通常していることです:
if Rails.env.production?
request.remote_ip
else
Net::HTTP.get(URI.parse('http://checkip.amazonaws.com/')).squish
end
URLへのアクセス方法によって異なります。
http://127.0.0.1/....
またはhttp://localhost/....
を使用してURLにアクセスすると、リモートIPとして127.0.0.1
が取得されます。 LANを使用している場合は、http:// {lan-ip}/....を使用します.
例えばhttp://172.20.25.210/.......
私は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
そしてそれは魅力のように働いた! :)
実際のIPを使用して開発マシンにアクセスする場合は、実際のIPを取得する必要があるため、localhostを使用せずに、実際のIPを使用します。すべてのルーターが、実際にそのLAN上にある外部IPアドレスへのマシンへのLANアクセスを許可するわけではありませんが、ほとんどは許可します。
問題:
最近、プロジェクトで同様のことをしようとしていて、コードで_request.remote_ip
_を使用するのに問題がありました。 _127.0.0.1
_または_::1
_を返し続けました。 Geocoder gemと組み合わせると、空の配列が得られ、基本的には役に立ちませんでした。
解決策:
telize.com にはすてきなAPIがあり、ヒットしたもののIPアドレスを返します。実装したコードは次のようになりました。
location = Geocoder.search(HTTParty.get('http://www.telize.com/ip').body)
Rails-yを使用する方法としてはほとんどありませんが、ローカルおよび実稼働環境でも機能するため、これは非常に優れたソリューションだと思います。唯一の潜在的な問題は、APIの制限に達した場合ですが、小規模なプロジェクトの場合、これは問題ではないはずです。
私はこれをしなければなりませんでした:
require 'socket'
Socket.ip_address_list.detect(&:ipv4_private?)&.ip_address