web-dev-qa-db-fra.com

Obtention d'un nom de pays d'utilisateur à partir de l'adresse IP d'origine avec Ruby on Rails

Je souhaite extraire un nom de pays d'utilisateur des adresses IP des visiteurs.

Je pourrais obtenir l'adresse IP avec remote_ip. Mais quel pourrait être le moyen le plus facile d’obtenir le nom du pays?

Il n'est pas nécessaire que ce soit super précis. Une bibliothèque Ruby (gem ou plugin) pour le faire?

Je veux une solution simple et facile pour cela.

33
TK.

Vous pouvez utiliser geoip gem.

environment.rb

config.gem 'geoip'

Téléchargez GeoIP.dat.gz à partir de http://www.maxmind.com/app/geolitecountry. Décompressez le fichier. La liste ci-dessous est définie sous #{Rails_ROOT}/db dir.

@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
48
Chandra Patni

Vous pouvez également utiliser " Geocoder "

Cela vous facilitera simplement la vie. Mettez la ligne suivante dans votre Gemfile et lancez la commande bundle install

gem 'geocoder'

En utilisant cette gemme, vous pouvez facilement obtenir le pays, l'adresse IP ou même la ville de l'adresse IP d'origine. Voir un exemple ci-dessous

request.ip  # =>    "182.185.141.75"
request.location.city   # =>    ""
request.location.country    # =>    "Pakistan"
26
Nadeem Yasin

J'utilise ce 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"
9
stef

Le plus simple consiste à utiliser un service Web existant à cet effet.

Il existe des plugins qui vous permettent de faire beaucoup plus, notamment en rendant vos modèles sensibles à la géolocalisation (geokit-Rails) automatiquement, mais si vous avez simplement besoin d'un code de pays, envoyez simplement un HTTP Get à http://api.hostip.info/country.php (il existe d'autres services mais ceci on ne nécessite pas de clé API) le renverra, par exemple :

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


Ou polling http://api.hostip.info/ renverra une réponse XML complète avec la ville, la latitude, la longitude, etc.

Sachez que les résultats que vous obtenez ne sont pas précis à 100%. Par exemple, en ce moment je suis en France mais rapporté comme en Allemagne. Ce sera le cas pour à peu près n'importe quel service basé sur IP.

6
JRL

Un service que vous pouvez utiliser pour ce faire est le mien, https://ipinfo.io . Il vous donne le code du pays et une foule d'autres détails:

$ 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"
}

Si vous voulez juste le pays, vous pouvez l'obtenir en demandant /country

$ curl ipinfo.io/country
US

Vous pouvez ensuite mapper un code de pays sur un nom à l'aide des données de http://country.io ou de l'exemple présenté à http://ipinfo.io/developers/full-country-names

4
Ben Dowling

Je viens de publier une gemme pour l'API IPLocate.io que j'ai créée.

Super facile, pas de bases de données à télécharger, et 1 500 demandes gratuites par jour:

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"
# }  

Pas de gemme

Il peut également être utilisé sans joyau en utilisant simplement les Net::HTTP et URI de Ruby:

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

La demande renverra JSON afin que vous puissiez l'analyser et y accéder comme suit:

country = JSON.parse( response )["country"]
# => "US"
2
ttarik

Vous pouvez essayer Yandex locator gem , le service renvoie la longitude, la latitude et la précision.

conn = YandexLocator::Client.new
result = conn.lookup(ip: "109.252.52.39")
# => {"position"=>{"altitude"=>0.0, "altitude_precision"=>30.0, "latitude"=>55.75395965576172, "longitude"=>37.62039184570312, "precision"=>100000.0, "type"=>"ip"}}
1
Sergey Chechaev

Voici un exemple Ruby appelant le ipdata.co API.

Il est rapide et offre des performances fiables grâce à 10 points d'extrémité globaux capables chacun de traiter plus de 10 000 requêtes par seconde!

Cette réponse utilise une clé API 'test' très limitée et destinée uniquement à tester quelques appels. Signup pour votre propre clé d’API gratuite et recevez jusqu’à 1500 demandes de développement par jour.

Remplacez 78.8.53.5 par l'adresse IP que vous souhaitez rechercher.

require 'rubygems' if Ruby_VERSION < '1.9'
require 'rest_client'

headers = {
  :accept => 'application/json'
}

response = RestClient.get 'https://api.ipdata.co/78.8.53.5?api-key=test', headers
puts response

Ça vous donnerait

{
    "ip": "78.8.53.5",
    "is_eu": true,
    "city": "G\u0142og\u00f3w",
    "region": "Lower Silesia",
    "region_code": "DS",
    "country_name": "Poland",
    "country_code": "PL",
    "continent_name": "Europe",
    "continent_code": "EU",
    "latitude": 51.6557,
    "longitude": 16.089,
    "asn": "AS12741",
    "organisation": "Netia SA",
    "postal": "67-200",
    "calling_code": "48",
    "flag": "https://ipdata.co/flags/pl.png",
    "emoji_flag": "\ud83c\uddf5\ud83c\uddf1",
    "emoji_unicode": "U+1F1F5 U+1F1F1",
    "carrier": {
        "name": "Netia",
        "mcc": "260",
        "mnc": "07"
    },
    "languages": [
        {
            "name": "Polish",
            "native": "Polski"
        }
    ],
    "currency": {
        "name": "Polish Zloty",
        "code": "PLN",
        "symbol": "z\u0142",
        "native": "z\u0142",
        "plural": "Polish zlotys"
    },
    "time_zone": {
        "name": "Europe/Warsaw",
        "abbr": "CEST",
        "offset": "+0200",
        "is_dst": true,
        "current_time": "2018-08-29T15:34:23.518065+02:00"
    },
    "threat": {
        "is_tor": false,
        "is_proxy": false,
        "is_anonymous": false,
        "is_known_attacker": false,
        "is_known_abuser": false,
        "is_threat": false,
        "is_bogon": false
    },
}
1
Jonathan

Essayez le Ruby IP2Location

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

Prérequis

Téléchargez gratuitement la base de données LITE à partir de http://lite.ip2location.com/ et utilisez ci-dessous.

Installer

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
Vlam

La gemme geoip ne fonctionne plus avec les nouvelles bases de données MaxMind. Il existe un nouveau joyau qui fait cela, MaxMind-DB-Reader-Ruby .

Téléchargez simplement les bases de données binaires Ville ou Pays, gzippées à partir de MaxMind , décompressez-les et utilisez le type de code suivant:

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

Adaptez-vous en fonction de vos besoins. J'ai créé une méthode dans un initialiseur que je peux appeler si nécessaire.

0
Artelius