代码之家  ›  专栏  ›  技术社区  ›  TK.

使用ruby on rails从原始ip地址获取用户名

  •  33
  • TK.  · 技术社区  · 15 年前

    我想从访问者的IP地址中提取一个用户名。

    我可以用 remote_ip . 但可能是什么 最简单的方法得到国家的名字?

    它不必非常精确。有没有Ruby库(gem或插件)可以做到这一点?

    我想要一个简单易行的解决方案。

    10 回复  |  直到 6 年前
        1
  •  48
  •   Chandra Patni    15 年前

    你可以使用 geoip 宝石。

    环境.rb

    config.gem 'geoip'
    

    下载 GeoIP.dat.gz http://www.maxmind.com/app/geolitecountry . 解压缩文件。下面假设 #{RAILS_ROOT}/db 迪尔

    @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
    
        2
  •  26
  •   Nadeem Yasin dule    12 年前

    你也可以使用“ Geocoder

    它只会让你的生活更轻松。在gemfile中输入以下行并发出bundle install命令

    gem 'geocoder'
    

    使用此gem,您可以很容易地获得原始ip的国家、ip甚至城市。参见下面的示例

    request.ip  # =>    "182.185.141.75"
    request.location.city   # =>    ""
    request.location.country    # =>    "Pakistan"
    
        3
  •  9
  •   stef    13 年前

    我用这一行:

    locale = Timeout::timeout(5) { Net::HTTP.get_response(URI.parse('http://api.hostip.info/country.php?ip=' + request.remote_ip )).body } rescue "US"
    
        4
  •  6
  •   JRL    15 年前

    最简单的方法是为此使用现有的web服务。

    有一些插件可以让您做更多的事情,包括让您的模型自动感知地理位置(geokit rails),但是如果您只需要一个国家代码(例如),只需发送一个http get到 http://api.hostip.info/country.php (还有其他服务,但此服务不需要API密钥)将返回该服务,例如:

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


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

    请注意,您得到的结果并非100%准确。例如,我现在在法国,但在德国有报道。几乎所有基于IP的服务都是这样。

        5
  •  4
  •   Ben Dowling    8 年前

    你可以用我自己的服务来做这件事, 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"
    }
    

    如果你只想要这个国家,你可以通过请求 /country

    $ curl ipinfo.io/country
    US
    

    然后,您可以使用来自 http://country.io ,或使用 http://ipinfo.io/developers/full-country-names

        6
  •  2
  •   Joshua Pinter    7 年前

    我刚刚出版了一本 IPLocate.io API 是我创造的。

    超级简单,无需下载数据库,每天有1500个免费请求:

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

    无宝石

    它也可以在没有宝石的情况下使用,只需使用ruby的 Net::HTTP URI :

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

    请求将返回json,因此您可以按如下方式解析和访问它:

    country = JSON.parse( response )["country"]
    # => "US"
    
        7
  •  1
  •   Sergey Chechaev    9 年前

    你可以试试 Yandex locator gem ,服务返回经度、纬度和精度。

    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"}}
    
        8
  •  1
  •   Jonathan    7 年前

    下面是一个ruby示例,它调用 ipdata.co 应用程序编程接口。

    它速度快,性能可靠,因为有10个全局终结点,每个都能够处理每秒10000个请求!

    这个答案使用了一个非常有限的“test”api密钥,只用于测试几个调用。 Signup 对于您自己的免费api密钥,每天最多可以获得1500个开发请求。

    替换 78.8.53.5 你想查的任何IP

    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
    

    那会给你

    {
        "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
        },
    }
    
        9
  •  0
  •   Vlam    7 年前

    试试ip2location ruby

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

    先决条件

    从下载免费的lite数据库 http://lite.ip2location.com/ 在下面使用。

    安装

    gem install ip2location_ruby
    

    用法

    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"
    
        10
  •  0
  •   Artelius    6 年前

    这个 geoip gem不再适用于新的maxmind数据库。有一种新的宝石能做到这一点, MaxMind-DB-Reader-ruby .

    只需从 MaxMind ,解压缩并使用以下类型的代码:

    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
    

    根据你的需要调整。我在初始化器中创建了一个方法,可以根据需要调用它。