Rails - как получить IP-адрес посетителей?

Мне нужно сохранить IP-адрес посетителей в нашей базе данных, и вот как я пытаюсь это сделать:

@ip = request.remote_ip
@ip = request.env['REMOTE_ADDR']

Но в обоих случаях переменная @ip сохраняла значение 127.0.0.1, даже когда я развертываю приложение в экземпляре Amazon EC2.

Когда я проверяю http://www.whatismyip.com/, он показывает мой IP как 109.175.XXX.X.

Таким образом, почему переменная ruby ​​всегда отображает адрес 127.0.0.1? Как получить реальный IP-адрес?


EDIT: Здесь выводится следующее:

request.env['HTTP_X_FORWARDED_FOR'] => 
request.remote_ip => 127.0.0.1
request.env['REMOTE_ADDR'] => 127.0.0.1
request.ip => 127.0.0.1

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

Я решаю эту проблему целый день и до сих пор не добился успеха.

Спасибо

Ответ 1

Когда вы посещаете сайт локально, вы приходите с локального IP-адреса, то есть 127.0.0.1.

То, что вы делаете, это правильный путь к IP-адресу посетителей, и результат, который вы видите, является ожидаемым.

Вы хотите использовать

@ip = request.remote_ip

потому что это учитывает большинство случаев обратных прокси-серверов и другие ситуации, с которыми вы можете столкнуться, когда request.env['REMOTE_ADDR'] может иметь значение nil или адрес локального прокси.

Если у вас действительно есть обратный прокси-сервер перед вашим сервером приложений (и вы, вероятно, делаете это), вам нужно убедиться, что он устанавливает правильные заголовки при пересылке запросов. Как минимум, заголовок X-Forwarded-For должен быть установлен.

Пример конфигурации nginx

Если вы используете nginx в качестве обратного прокси-сервера перед вашим Rails-приложением (то есть с использованием proxy_pass), вам нужно настроить его так, чтобы добавить соответствующие заголовки к отправляемому запросу. В случае X-Forwarded-For это делается с помощью:

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

Вы также можете настроить следующее, чтобы nginx пересылал запрошенное имя хоста и протоколы:

# enable this if you forward HTTPS traffic to Rails,
# this helps Rack set the proper URL scheme for doing redirects:
proxy_set_header X-Forwarded-Proto $scheme;

# pass the Host: header from the client right along so redirects
# can be set properly within the Rack application
proxy_set_header Host $http_host;

Ответ 2

Получить IP-адрес клиента с помощью команды:

request.remote_ip

Ответ 3

Обратите внимание, что если вы используете AWS с любым из поставляемых им балансировщиков нагрузки, вам может потребоваться настроить эти балансировщики нагрузки соответствующим образом, чтобы они перенаправили IP-адрес клиента.

Обычно переполнению стека не нравятся ответы, которые являются просто ссылкой, но в данном случае, поскольку вопрос очень старый, и мы не предоставляем подробных сведений для ответа на конкретный вопрос, а также из-за того, какой тип балансировщиков нагрузки предлагает AWS и как его настроить. они постоянно меняются, я просто опубликую ссылку на инструкции базы знаний AWS для пересылки IP-адреса клиента через балансировщик нагрузки.

Подобные проблемы могут возникнуть, если вы используете сеть доставки контента (CDN) для доставки данных, и в этом случае вам необходимо обратиться к вашему поставщику CDN за инструкциями.

@Jakob S правильно объясняет, как настроить nginx для передачи X-Forwarded-For, который является текущим стандартом де-факто, но префикс X- означает, что он явно нестандартен в соответствующей спецификации HTTP. В конце концов вы можете захотеть поддержать заголовок Forwarded, который указан в RFC 7239, но на данный момент (январь 2019) он не получил широкого распространения и не стоит переходить на него из-за отсутствия широкой поддержки.

Ответ 4

х-пересылаются-за. x-forwarded-for (XFF) - это стандартный прокси-заголовок, который указывает IP-адреса, через которые прошел запрос на пути от клиента к серверу.

В моей конфигурации сервера nginx у меня было,

proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;

Я получал удаленный IP-адрес клиента, как показано ниже,

request.env['HTTP_X_FORWARDED_FOR'] || request.remote_ip

Примечание: это может быть неправильный IP-адрес, если клиент сидит за прокси.