Getting a user country name from originating IP address with Ruby on Rails

前端 未结 11 1531
一整个雨季
一整个雨季 2020-12-04 08:26

I want to extract a user country name from visitors\' IP addresses.

I could get the IP address with remote_ip. But what could be the easiest way to get

相关标签:
11条回答
  • 2020-12-04 08:48

    The gem geoip can be replaced with the new gem maxminddb. It support new MaxMind db format.

    db = MaxMindDB.new('./GeoLite2-City.mmdb')
    ret = db.lookup('74.125.225.224')
    
    ret.found? # => true
    ret.country.name # => 'United States'
    ret.country.name('zh-CN') # => '美国'
    ret.country.iso_code # => 'US'
    ret.city.name(:fr) # => 'Mountain View'
    ret.subdivisions.most_specific.name # => 'California'
    ret.location.latitude # => -122.0574
    
    0 讨论(0)
  • 2020-12-04 08:57

    Try the IP2Location Ruby

    https://github.com/ip2location/ip2location-ruby

    Pre-requisite

    Download the free LITE database from http://lite.ip2location.com/ and use below.

    Install

    gem install ip2location_ruby
    

    Usage

    require 'ip2location_ruby'
    
    i2l = Ip2location.new.open("./data/IP-COUNTRY-SAMPLE.BIN")
    record = i2l.get_all('8.8.8.8')
    
    print 'Country Code: ' + record.country_short + "\n"
    print 'Country Name: ' + record.country_long + "\n"
    print 'Region Name: ' + record.region + "\n"
    print 'City Name: ' + record.city + "\n"
    print 'Latitude: '
    print record.latitude
    print "\n"
    print 'Longitude: '
    print record.longitude
    print "\n"
    print 'ISP: ' + record.isp + "\n"
    print 'Domain: ' + record.domain + "\n"
    print 'Net Speed: ' + record.netspeed + "\n"
    print 'Area Code: ' + record.areacode + "\n"
    print 'IDD Code: ' + record.iddcode + "\n"
    print 'Time Zone: ' + record.timezone + "\n"
    print 'ZIP Code: ' + record.zipcode + "\n"
    print 'Weather Station Code: ' + record.weatherstationname + "\n"
    print 'Weather Station Name: ' + record.weatherstationcode + "\n"
    print 'MCC: ' + record.mcc + "\n"
    print 'MNC: ' + record.mnc + "\n"
    print 'Mobile Name: ' + record.mobilebrand + "\n"
    print 'Elevation: '
    print record.elevation
    print "\n"
    print 'Usage Type: ' + record.usagetype + "\n"
    
    0 讨论(0)
  • 2020-12-04 08:58

    I'm using this one-liner:

    locale = Timeout::timeout(5) { Net::HTTP.get_response(URI.parse('http://api.hostip.info/country.php?ip=' + request.remote_ip )).body } rescue "US"
    
    0 讨论(0)
  • 2020-12-04 09:01

    The simplest is to use an existing web service for this.

    There are plugins that let you do much more, including making your models geolocation-aware (geokit-rails) automatically, but if all you need is a country code for example, simply sending an HTTP Get to http://api.hostip.info/country.php (there are other services but this one does not require an API key) will return it, e.g. :

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


    Or polling http://api.hostip.info/ will return a full XML response with city, latitude, longitude, etc.

    Be aware that the results you get are not 100% accurate. For example, right now I'm in France but reported as in Germany. This will be the case for pretty much any IP-based service.

    0 讨论(0)
  • 2020-12-04 09:03

    I've just published a gem for the IPLocate.io API which I created.

    Super easy, no databases to download, and 1,500 free requests per day:

    require 'iplocate'
    
    # Look up an IP address
    results = IPLocate.lookup("8.8.8.8")
    
    # Or with an API key
    results = IPLocate.lookup("8.8.8.8", "abcdef")
    
    results["country"]
    # "United States"
    
    results["country_code"]
    # "US"
    
    results["org"]
    # "Google LLC"
    
    results.inspect
    # {
    #   "ip"=>"8.8.8.8",
    #   "country"=>"United States",
    #   "country_code"=>"US",
    #   "city"=>nil,
    #   "continent"=>"North America",
    #   "latitude"=>37.751,
    #   "longitude"=>-97.822,
    #   "time_zone"=>nil,
    #   "postal_code"=>nil,
    #   "org"=>"Google LLC",
    #   "asn"=>"AS15169"
    # }  
    

    No Gem

    It can also be used without a gem by just using Ruby's Net::HTTP and URI:

    response = Net::HTTP.get( URI.parse( "https://www.iplocate.io/api/lookup/8.8.8.8" ) )
    

    The request will return JSON so you can parse it and access it as follows:

    country = JSON.parse( response )["country"]
    # => "US"
    
    0 讨论(0)
提交回复
热议问题