Как определить IP-адрес пользователя в узле

273

Как определить IP-адрес данного запроса из контроллера? Например (в экспресс):

app.post('/get/ip/address', function (req, res) {
    // need access to IP address here
})
  • 15
    Если вы используете Express, вы можете использовать req.ip source - expressjs.com/en/api.html#req.ip
  • 0
    Попробуйте это: github.com/indutny/node-ip
Показать ещё 1 комментарий
Теги:
ip

15 ответов

359
Лучший ответ

В вашем объекте request существует свойство connection, которое является объектом net.Socket. Объект net.Socket имеет свойство remoteAddress, поэтому вы должны иметь возможность получить IP-адрес с помощью этого вызова:

request.connection.remoteAddress

См. документацию для http и net

ИЗМЕНИТЬ

Как отмечает @juand в комментариях, правильный метод получения удаленного IP-адреса, если сервер находится за прокси-сервером, составляет request.headers['x-forwarded-for']

  • 4
    Это дает мне IP-адрес, отличный от того, что дает мне whatismyip.com. С чего бы это?
  • 0
    Вы имеете в виду, что вы подключаетесь с localhost? Что это тебе дает?
Показать ещё 12 комментариев
347
var ip = req.headers['x-forwarded-for'] || 
     req.connection.remoteAddress || 
     req.socket.remoteAddress ||
     (req.connection.socket ? req.connection.socket.remoteAddress : null);

Обратите внимание, что иногда вы можете получить более одного IP-адреса в req.headers['x-forwarded-for']. Кроме того, заголовок x-forwarded-for не всегда будет установлен, что может вызвать ошибку.

Общий формат поля:

x-forwarded-for: client, proxy1, proxy2, proxy3

где значение представляет собой список IP-адресов, разделенных запятыми + пробелами, крайний левый - исходный клиент, и каждый последующий прокси-сервер, прошедший запрос, добавляет IP-адрес, с которого он получил запрос. В этом примере запрос прошел через proxy1, proxy2, а затем proxy3. proxy3 отображается как удаленный адрес запроса.

Это решение, предложенное Арнавом Гуптой с исправлением, предложенным Мартином ниже в комментариях для случаев, когда x-forwarded-for не установлен:

var ip = (req.headers['x-forwarded-for'] || '').split(',').pop() || 
         req.connection.remoteAddress || 
         req.socket.remoteAddress || 
         req.connection.socket.remoteAddress
  • 5
    Как предотвратить подделку этих заголовков?
  • 1
    Если вы находитесь за прокси-сервером, который устанавливает эти заголовки, он добавится в конец списка адресов. Последний будет установлен вашим прокси, предыдущие могут быть получены от предыдущих балансировщиков нагрузки или «подделаны» от клиента. Я полагаю, вы могли бы также сказать своему LB перезаписать заголовок.
Показать ещё 18 комментариев
28

Вы можете оставаться DRY и просто использовать node-ipware, который поддерживает как IPv4 и IPv6.

Установка:

npm install ipware

В вашем приложении app.js или промежуточном программном обеспечении:

var getIP = require('ipware')().get_ip;
app.use(function(req, res, next) {
    var ipInfo = getIP(req);
    console.log(ipInfo);
    // { clientIp: '127.0.0.1', clientIpRoutable: false }
    next();
});

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

  • 34
    "или возвращает 127.0.0.1, чтобы указать, что он не может определить IP-адрес пользователя" Существует довольно большая разница между 127.0.0.1 и неизвестным ...
  • 4
    Он вернул мне что-то странное :ffff:(not my IP address) при тестировании от Heroku. Ответ @ edmar-miyake работает правильно для меня.
Показать ещё 5 комментариев
27

Если используется экспресс...

req.ip

Я смотрел это, тогда я был как подождем, я использую выражение. Duh.

  • 0
    Это самый простой способ и должен быть выбранный ответ.
19

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

Раскрытие: я создал этот модуль

Установка:

npm install request-ip

В вашем приложении:

var requestIp = require('request-ip');

// inside middleware handler
var ipMiddleware = function(req, res, next) {
    var clientIp = requestIp.getClientIp(req); // on localhost > 127.0.0.1
    next();
};

Надеюсь, что это поможет

  • 1
    проверяя исходный код пакета request-ip по адресу github.com/pbojinov/request-ip/blob/master/index.js, он проверяет x-forwarded-for и все виды других заголовков для популярных балансировщиков нагрузки, таких как AWS ELB, Cloudflare , Akamai, nginx, Rackspace LB и Stingray от Riverbed
12

В соответствии с этой функцией все рассмотренные случаи помогут

var ip;
if (req.headers['x-forwarded-for']) {
    ip = req.headers['x-forwarded-for'].split(",")[0];
} else if (req.connection && req.connection.remoteAddress) {
    ip = req.connection.remoteAddress;
} else {
    ip = req.ip;
}console.log("client IP is *********************" + ip);
  • 0
    Обратите внимание, что у меня есть ips , для меня.
12

request.headers['x-forwarded-for'] || request.connection.remoteAddress

Если заголовок x-forwarded-for используется, используйте его, в противном случае используйте свойство .remoteAddress.

Заголовок x-forwarded-for добавляется к запросам, которые проходят через балансировщики нагрузки (или другие типы прокси), настроенные для HTTP или HTTPS (также возможно добавить этот заголовок запрашивает при балансировке на уровне TCP, используя протокол прокси-протокола). Это связано с тем, что свойство request.connection.remoteAddress будет содержать приватный IP-адрес балансировки нагрузки, а не публичный IP-адрес клиента. Используя оператор OR, в приведенном выше порядке вы проверяете наличие заголовка x-forwarded-for и используете его, если он существует, в противном случае используйте request.connection.remoteAddress.

6

Есть два способа получить IP-адрес:

  1. let ip = req.ip

  2. let ip = req.connection.remoteAddress;

Но есть проблема с вышеуказанными подходами.

Если вы запускаете свое приложение за Nginx или любым прокси, каждый IP-адрес будет 127.0.0.1.

Итак, лучшее решение для получения IP-адреса пользователя:

let ip = req.header('x-forwarded-for') || req.connection.remoteAddress;
6

function getCallerIP(request) {
    var ip = request.headers['x-forwarded-for'] ||
        request.connection.remoteAddress ||
        request.socket.remoteAddress ||
        request.connection.socket.remoteAddress;
    ip = ip.split(',')[0];
    ip = ip.split(':').slice(-1); //in case the ip returned in a format: "::ffff:146.xxx.xxx.xxx"
    return ip;
}
  • 0
    Это решение смущает возврат одноэлементного массива ...
  • 1
    Вы правы, если вы хотите, чтобы ip был строкой, тогда вы можете заменить последнюю строку на: ip = ip.split (':'). Slice (-1) [0]
6

Если вы используете экспресс-версию 3.x или выше, вы можете использовать настройку доверенного прокси (http://expressjs.com/api.html#trust.proxy.options.table), и она будет ходить по цепочке адресов в заголовке x-forwarded-for и поместите последний ip в цепочке, который вы не настроили как доверенный прокси-сервер в ip-свойство объекта req.

3

Простой доступ к удаленному ip в nodejs:

var ip = req.header('x-forwarded-for') || req.connection.remoteAddress;
2

Если вы получаете несколько IP-адресов, это работает для меня:

var ipaddress = (req.headers['x-forwarded-for'] || 
req.connection.remoteAddress || 
req.socket.remoteAddress || 
req.connection.socket.remoteAddress).split(",")[0];
1

Я понимаю, что на это ответили до смерти, но здесь я написал современную версию ES6, которая соответствует стандартам esbint на базе airbnb.

const getIpAddressFromRequest = (request) => {
  let ipAddr = request.connection.remoteAddress;

  if (request.headers && request.headers['x-forwarded-for']) {
    [ipAddr] = request.headers['x-forwarded-for'].split(',');
  }

  return ipAddr;
};

Заголовок X-Forwarded-For может содержать разделенный запятыми список IP-адресов прокси. Заказ клиентский, proxy1, proxy2,..., proxyN. В реальном мире люди внедряют прокси, которые могут предоставлять все, что они хотят в этом заголовке. Если вы находитесь за балансировщиком нагрузки или чем-то еще, вы можете, по крайней мере, доверять первому IP-адресу в списке, по крайней мере, любому прокси-серверу, через который поступил какой-либо запрос.

0

В узле 10.14 позади nginx вы можете получить ip, запросив его через заголовок nginx, например:

proxy_set_header X-Real-IP $remote_addr;

Тогда в вашем app.js:

app.set('trust proxy', true);

После этого везде, где вы хотите, чтобы оно появилось:

var userIp = req.header('X-Real-IP') || req.connection.remoteAddress;
-7

Имел ту же проблему... im также новичок в javascript, но я решил это с req.connection.remoteAddress; который дал мне IP-адрес (но в формате ipv6:: ffff.192.168.0.101), а затем .slice, чтобы удалить 7 первых цифр.

var ip = req.connection.remoteAddress;

if (ip.length < 15) 
{   
   ip = ip;
}
else
{
   var nyIP = ip.slice(7);
   ip = nyIP;
}
  • 0
    это не очень хороший метод, так как ipv6 - это НЕ просто 7 цифр + IPv4, но может быть совершенно другим.
  • 0
    @Radek, если вы проверяете начало адреса, он соответствует спецификации (см. En.wikipedia.org/wiki/IPv6_address ctrl-f для поиска «IPv4-mapped») ip= (ip.length<15?ip:(ip.substr(0,7)==='::ffff:'?ip.substr(7):undefined)) заменит if ... в приведенном выше коде
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню