Я не совсем понимаю, как мне получить IP-адрес удаленного пользователя.
Скажем, у меня есть простой маршрут запроса, например:
app.get(/, function (req, res){
var forwardedIpsStr = req.header('x-forwarded-for');
var IP = '';
if (forwardedIpsStr) {
IP = forwardedIps = forwardedIpsStr.split(',')[0];
}
});
Правильно ли этот подход подходит для получения реального IP-адреса пользователя или есть лучший способ?
А как насчет прокси?
Ответ 1
Если вы работаете за прокси, например NGiNX или что у вас есть, только тогда вы должны проверить "x-forwarded-for":
var ip = req.headers['x-forwarded-for'] || req.connection.remoteAddress;
Если прокси не является "вашим", я бы не стал доверять заголовку "x-forwarded-for", потому что он может быть подделан.
Ответ 2
Хотя ответ от @alessioalex работает, существует другой способ, указанный в разделе "Экспресс за прокси-серверами" в Express - руководство.
- Добавьте
app.set('trust proxy', true)
в код экспресс-инициализации.
- Если вы хотите получить IP-адрес удаленного клиента, используйте
req.ip
или req.ips
обычным способом (как если бы не было обратного прокси-сервера)
Дополнительное чтение:
- Используйте
req.ip
или req.ips
. req.connection.remoteAddress
не работает с этим решением.
- Дополнительные опции для
'trust proxy'
доступны, если вам нужно что-то более сложное, чем доверять всему, что пропущено в заголовке x-forwarded-for
(например, когда ваш прокси-сервер не удаляет существующий заголовок x-forwarded-for из ненадежных источников). Смотрите подробности в связанном руководстве.
- Если ваш прокси-сервер не заполняет заголовок
x-forwarded-for
, есть две возможности.
- Прокси-сервер не передает информацию о том, где изначально был запрос. В этом случае не было бы способа выяснить, откуда исходил запрос. Вам необходимо сначала изменить конфигурацию прокси-сервера.
- Например, если вы используете nginx в качестве обратного прокси-сервера, вам может потребоваться добавить
proxy_set_header X-Forwarded-For $remote_addr;
в вашу конфигурацию.
- Прокси-сервер ретранслирует информацию о том, откуда исходил запрос, в проприетарной форме (например, пользовательский заголовок http). В таком случае этот ответ не будет работать. Может быть специальный способ получить эту информацию, но вам нужно сначала понять механизм.
Ответ 3
В nginx.conf
файле:
proxy_set_header X-Real-IP $remote_addr;
В node.js
файле сервера:
var ip = req.headers['x-real-ip'] || req.connection.remoteAddress;
обратите внимание, что выражать заголовки нижних регистров
Ответ 4
В частности, для node в документации для компонента http-сервера в подключение к событию говорится:
[Triggered], когда установлен новый поток TCP. [The] - это объект типа net.Socket. Обычно пользователи не хотят получать доступ к этому событию. В в частности, сокет не будет выдавать читаемые события из-за того, как парсер протокола присоединяется к сокету. Сокет также может быть доступ к request.connection
.
Итак, это означает, что request.connection
является сокетом, и в соответствии с документацией действительно есть атрибут socket.remoteAddress, который согласно документации является:
Строковое представление удаленного IP-адреса. Например, '74.125.127.100 'или' 2001: 4860: a005:: 68 '.
В выраженном выражении объект запроса также является экземпляром объекта запроса Node http, поэтому этот подход все равно должен работать.
Однако в Express.js запрос уже имеет два атрибута: req.ip и req.ips
req.ip
Верните удаленный адрес или когда включен "доверенный прокси" - адрес восходящего канала.
req.ips
Когда "доверенный прокси" является true
, проанализируйте список адресов ip-адресов "X-Forwarded-For" и верните массив, иначе пустой массив вернулся. Например, если значение было "client, proxy1, proxy2", вы получит массив [ "client", "proxy1", "proxy2" ], где "proxy2" является самым далеким потоком.
Возможно, стоит упомянуть, что, по моему мнению, Express req.ip
является лучшим подходом, чем req.connection.remoteAddress
, поскольку req.ip
содержит фактический клиентский ip (при условии, что доверенный прокси включен в экспресс), тогда как другой может содержать IP-адрес прокси (если таковой имеется).
Вот почему предлагаемый в настоящее время ответ предполагает:
var ip = req.headers['x-forwarded-for'] ||
req.connection.remoteAddress;
req.headers['x-forwarded-for']
будет эквивалентным выражению req.ip
.
Ответ 5
- Добавить
app.set('trust proxy', true)
- Используйте
req.ip
или req.ips
обычным способом
Ответ 6
В соответствии с Express за прокси-серверами req.ip
учитывает обратный прокси-сервер, если вы правильно настроили trust proxy
. Поэтому он лучше, чем req.connection.remoteAddress
, который получается из сетевого уровня и не знает прокси.
Ответ 7
Это просто дополнительная информация для этого ответа.
Если вы используете nginx
, вы должны добавить proxy_set_header X-Real-IP $remote_addr;
в блок локации для сайта. /etc/nginx/sites-available/www.example.com
например. Вот пример блока сервера.
server {
listen 80;
listen [::]:80;
server_name example.com www.example.com;
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_pass http://127.0.1.1:3080;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
После перезапуска nginx
вы сможете получить доступ к ip в маршрутах вашего node
/express
приложения с помощью req.headers['x-real-ip'] || req.connection.remoteAddress;
req.headers['x-real-ip'] || req.connection.remoteAddress;
Ответ 8
Просто используйте это промежуточное ПО Express https://www.npmjs.com/package/express-ip
Вы можете установить модуль используя
npm i express-ip
использование
const express = require('express');
const app = express();
const expressip = require('express-ip');
app.use(expressip().getIpInfoMiddleware);
app.get('/', function (req, res) {
console.log(req.ipInfo);
});
Ответ 9
Это работало для меня лучше остальных. Мои сайты находятся за CloudFlare, и, похоже, для этого требуется cf-connecting-ip
.
req.headers['cf-connecting-ip'] || req.headers['x-forwarded-for'] || req.connection.remoteAddress
Не тестировал Экспресс за прокси-серверами, поскольку он ничего не сказал об этом заголовке cf-connecting-ip
.
Ответ 10
У объекта заголовков есть все, что вам нужно, просто сделайте это:
var ip = req.headers['x-forwarded-for'].split(',')[0];
Ответ 11
Я знаю, что на этот вопрос ответили, но вот как я заставил мою работу.
let ip = req.connection.remoteAddress.split(':').pop();
Ответ 12
var ip = req.connection.remoteAddress;
ip = ip.split(':') [3];
Ответ 13
С поддержкой fla-flare, nginx и x-real-ip
var user_ip;
if(req.headers['cf-connecting-ip'] && req.headers['cf-connecting-ip'].split(', ').length) {
let first = req.headers['cf-connecting-ip'].split(', ');
user_ip = first[0];
} else {
let user_ip = req.headers['x-forwarded-for'] || req.headers['x-real-ip'] || req.connection.remoteAddress || req.socket.remoteAddress || req.connection.socket.remoteAddress;
}