Express.js: как получить удаленный адрес клиента

Я не совсем понимаю, как мне получить 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 - руководство.

  1. Добавьте app.set('trust proxy', true) в код экспресс-инициализации.
  2. Если вы хотите получить IP-адрес удаленного клиента, используйте req.ip или req.ips обычным способом (как если бы не было обратного прокси-сервера)

Дополнительное чтение:

  • Используйте req.ip или req.ips. req.connection.remoteAddress не работает с этим решением.
  • Дополнительные опции для 'trust proxy' доступны, если вам нужно что-то более сложное, чем доверять всему, что пропущено в заголовке x-forwarded-for (например, когда ваш прокси-сервер не удаляет существующий заголовок x-forwarded-for из ненадежных источников). Смотрите подробности в связанном руководстве.
  • Если ваш прокси-сервер не заполняет заголовок x-forwarded-for, есть две возможности.
    1. Прокси-сервер не передает информацию о том, где изначально был запрос. В этом случае не было бы способа выяснить, откуда исходил запрос. Вам необходимо сначала изменить конфигурацию прокси-сервера.
      • Например, если вы используете nginx в качестве обратного прокси-сервера, вам может потребоваться добавить proxy_set_header X-Forwarded-For $remote_addr; в вашу конфигурацию.
    2. Прокси-сервер ретранслирует информацию о том, откуда исходил запрос, в проприетарной форме (например, пользовательский заголовок 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;
    }