Геокодер, как проверить локально, когда ip 127.0.0.1?

Я не могу заставить геокодер работать правильно, так как мой локальный IP-адрес 127.0.0.1, поэтому он не может правильно определить мое местонахождение.

В request.location.ip отображается «127.0.0.1».

Как я могу использовать другой IP-адрес (IP-адрес моего интернет-соединения), чтобы он приносил больше релевантных данных?


person Blankman    schedule 24.05.2011    source источник


Ответы (6)


Хороший чистый способ сделать это — использовать MiddleWare. Добавьте этот класс в каталог lib:

# lib/spoof_ip.rb

class SpoofIp
  def initialize(app, ip)
    @app = app
    @ip = ip
  end

  def call(env)
    env['HTTP_X_FORWARDED_FOR'] = nil
    env['REMOTE_ADDR'] = env['action_dispatch.remote_ip'] = @ip
    @status, @headers, @response = @app.call(env)
    [@status, @headers, @response]
  end
end

Затем найдите IP-адрес, который вы хотите использовать для своей среды разработки, и добавьте его в свой файл development.rb:

config.middleware.use('SpoofIp', '64.71.24.19')
person Sean Rucker    schedule 18.01.2012
comment
вероятно, это нуб, но вам нужно будет добавить что-то, например, в config/application.rb для автоматической загрузки этого класса, например: config.autoload_paths += Dir[#{config.root}/lib/**/] - person Will; 02.01.2013
comment
Я пробовал этот метод много лет назад, он работал потрясающе. Недавно попробовал еще раз в другом приложении, не помогло. Примерно через 2 часа я попытался понизить версию геокодера... и это сработало! Версия геокодера, с которой я это делал изначально, была 1.1.2 версия, которую я установил сегодня, была 1.1.6, поэтому что-то должно было измениться в этих версиях - person DickieBoy; 17.01.2013
comment
@DickieBoy, вы правы, этот метод не работает с Geocoder 1.1.6 из-за следующего изменить. Решение делает env['HTTP_X_FORWARDED_FOR'] = nil, но не удаляет ключ из хеша, поэтому он выбирается методом location, а поиск nil выполняется геокодером. Комментирование этой строки работает в моем случае. - person deivid; 18.02.2013
comment
FWIW Я могу подтвердить указанное выше исправление @deivid для Rails 4.0.0, используя гем Geocoder 1.1.8. Следование ответу @Ruckstar и комментирование строки env['HTTP_X_FORWARDED_FOR'] = nil помогает. - person Jason; 13.09.2013
comment
У меня это не работает, с комментированием строки Джейсона или без него, я встречаю следующую ошибку: .rvm/gems/ruby-2.0.0-p247/gems/activesupport-4.0.0.rc1/lib/active_support/inflector/methods.rb:226:in 'const_get': uninitialized constant SpoofIp (NameError) - person Flo Rahl; 16.09.2013
comment
Это работает в rails 4, либо добавьте путь автозагрузки для lib, либо переместите его в каталог инициализатора. - person Igrabes; 26.08.2016
comment
Если у вас возникли проблемы, попробуйте перезагрузить Spring (если вы его используете). Это исправило это для меня - person Mini John; 12.08.2020

Для этого я обычно использую params[:ip] или что-то в разработке. Это позволяет мне проверять другие IP-адреса на работоспособность и притворяться, что я нахожусь в любой точке мира.

Например

class ApplicationController < ActionController::Base
  def request_ip
    if Rails.env.development? && params[:ip]
      params[:ip]
    else
      request.remote_ip
    end 
  end
end
person jesse reiss    schedule 24.05.2011
comment
Я не знаком с геокодером, который, как я полагаю, является драгоценным камнем или чем-то в этом роде, но я думаю, что есть способ его настроить. Я использую GeoIP для геокодирования: geoip.rubyforge.org, и с этим достаточно легко работать, используя этот метод. - person jesse reiss; 25.05.2011
comment
Вы находитесь в среде разработки, поэтому нет возможности использовать реальный IP-адрес запросов. Вам нужно найти способ сообщить геокодеру, что в процессе разработки он должен использовать другое значение. - person jesse reiss; 25.05.2011

Я реализовал это немного иначе, и это хорошо работает для моего случая.

В application_controller.rb у меня есть метод поиска, который вызывает поиск IP-адреса геокодера, напрямую передавая результаты request.remote_ip.

def lookup_ip_location
  if Rails.env.development?
    Geocoder.search(request.remote_ip).first
  else
    request.location
  end
end

Затем в config/environments/development.rb я исправил вызов remote_ip:

class ActionDispatch::Request
  def remote_ip
    "71.212.123.5" # ipd home (Denver,CO or Renton,WA)                                                                                                                                                                                                                                                                        
    # "208.87.35.103" # websiteuk.com -- Nassau, Bahamas                                                                                                                                                                                                                                                                      
    # "50.78.167.161" # HOL Seattle, WA                                                                                                                                                                                                                                                                                       
  end
end

Я просто жестко закодировал некоторые адреса, но вы можете делать здесь все, что хотите.

person ipd    schedule 11.06.2013
comment
Я обнаружил, что для правильной работы request.location мне пришлось изменить этот ответ, переименовав метод lookup_ip_location просто в location и поместив его в этот класс ActionDispatch::Request. - person fabsays; 30.09.2015

У меня такой же вопрос. Вот как я реализовал с помощью геокодера.

#gemfile
gem 'httparty', :require => 'httparty', :group => :development 

#application_controller
def request_ip
  if Rails.env.development? 
     response = HTTParty.get('http://api.hostip.info/get_html.php')
     ip = response.split("\n")
     ip.last.gsub /IP:\s+/, ''      
   else
     request.remote_ip
   end 
end

#controller
ip = request_ip
response = Geocoder.search(ip)

(часть кода с hostip.info из драгоценного камня geo_magic и основана на другом ответе на этот вопрос.)

теперь вы можете сделать что-то вроде response.first.state

person BlissOfBeing    schedule 21.06.2011

Это обновленный ответ для геокодера 1.2.9, чтобы предоставить жестко закодированный IP-адрес для сред разработки и тестирования. Просто поместите это внизу вашего config/initilizers/geocoder.rb:

if %w(development test).include? Rails.env
  module Geocoder
    module Request
      def geocoder_spoofable_ip_with_localhost_override
        ip_candidate = geocoder_spoofable_ip_without_localhost_override
        if ip_candidate == '127.0.0.1'
          '1.2.3.4'
        else
          ip_candidate
        end
      end
      alias_method_chain :geocoder_spoofable_ip, :localhost_override
    end
  end
end
person kross    schedule 24.08.2015
comment
alias_method_chain устарел в Rails 5, поэтому этот ответ больше не актуален - person Viktor; 13.11.2017

вы также можете сделать это

request.safe_location
person Asnad Atta    schedule 10.03.2016
comment
Это возвращает тот же результат, что и request.location для меня. Какую разницу вы видите? - person Jon Worek; 03.12.2016