使用Ruby on Rails从原始IP地址获取用户国家/地区名称

TK.*_*TK. 33 ruby-on-rails ip-geolocation

我想从访问者的IP地址中提取用户国家/地区名称.

我可以获得IP地址remote_ip.但是获得国名的最简单方法是什么?

它不一定非常准确.任何ruby库(gem或插件)都可以做到这一点?

我想要一个简单易用的解决方案.

Cha*_*tni 48

你可以使用geoipgem.

的environment.rb

config.gem 'geoip'
Run Code Online (Sandbox Code Playgroud)

GeoIP.dat.gz从下载http://www.maxmind.com/app/geolitecountry.解压缩文件.以下假定在#{RAILS_ROOT}/dbdir 下.

@geoip ||= GeoIP.new("#{RAILS_ROOT}/db/GeoIP.dat")    
remote_ip = request.remote_ip 
if remote_ip != "127.0.0.1" #todo: check for other local addresses or set default value
  location_location = @geoip.country(remote_ip)
  if location_location != nil     
    @model.country = location_location[2]
  end
end
Run Code Online (Sandbox Code Playgroud)

  • 实际上,从geoip 1.1.1开始,您可以使用@ geoip.country(ip).country_name (2认同)

Nad*_*sin 28

你也可以使用" Geocoder "

它会让你的生活更轻松.将以下行放在Gemfile中并发出bundle install命令

gem 'geocoder'
Run Code Online (Sandbox Code Playgroud)

使用这个Gem,您可以轻松获得原始IP的国家,IP甚至城市.请参阅下面的示例

request.ip  # =>    "182.185.141.75"
request.location.city   # =>    ""
request.location.country    # =>    "Pakistan"
Run Code Online (Sandbox Code Playgroud)


ste*_*tef 9

我正在使用这个单行:

locale = Timeout::timeout(5) { Net::HTTP.get_response(URI.parse('http://api.hostip.info/country.php?ip=' + request.remote_ip )).body } rescue "US"
Run Code Online (Sandbox Code Playgroud)


JRL*_*JRL 6

最简单的方法是使用现有的Web服务.

有一些插件可以让你做更多的事情,包括让你的模型自动识别地理定位(geokit-rails),但如果你需要的只是一个国家代码,只需发送一个HTTP Get to http://api.hostip.info/country.php(还有其他服务但是这个不需要API密钥)会返回它,例如:

Net::HTTP.get_response(URI.parse('http://api.hostip.info/country.php'))
=> US
Run Code Online (Sandbox Code Playgroud)


或者轮询http://api.hostip.info/将返回包含城市,纬度,经度等的完整XML响应.

请注意,您获得的结果并非100%准确.例如,现在我在法国,但在德国报道.几乎任何基于IP的服务都是如此.


Art*_*ius 6

geoipgem 不再适用于新的 MaxMind 数据库。有一个新的 gem 可以做到这一点,MaxMind-DB-Reader-ruby

只需从MaxMind下载城市或国家二进制 gzip 数据库,解压缩,然后使用以下代码:

require 'maxmind/db'

reader = MaxMind::DB.new('GeoIP2-City.mmdb', mode: MaxMind::DB::MODE_MEMORY)

# you probably want to replace 1.1.1.1 with  request.remote_ip
# or request.env['HTTP_X_FORWARDED_FOR']
ip_addr = '1.1.1.1'
record = reader.get(ip_addr)
if record.nil?
  puts '#{ip_addr} was not found in the database'
else
  puts record['country']['iso_code']
  puts record['country']['names']['en']
end

reader.close
Run Code Online (Sandbox Code Playgroud)

根据您的需求进行调整。我在初始化程序中创建了一个方法,可以根据需要调用该方法。


Ben*_*ing 5

您可以使用的一项服务是我自己的服务https://ipinfo.io。它为您提供国家/地区代码和许多其他详细信息:

$ curl ipinfo.io
{
  "ip": "24.6.61.239",
  "hostname": "c-24-6-61-239.hsd1.ca.comcast.net",
  "city": "Mountain View",
  "region": "California",
  "country": "US",
  "loc": "37.3845,-122.0881",
  "org": "AS7922 Comcast Cable Communications, LLC",
  "postal": "94040"
}
Run Code Online (Sandbox Code Playgroud)

如果您只想要国家/地区,则可以通过请求 /country

$ curl ipinfo.io/country
US
Run Code Online (Sandbox Code Playgroud)

然后,您可以使用http://country.io中的数据或使用http://ipinfo.io/developers/full-country-names中的示例将国家/地区代码映射到名称。