Получите IP-адрес клиента в socket.io

133

При использовании socket.IO на сервере Node.js существует ли простой способ получить IP-адрес входящего соединения? Я знаю, что вы можете получить его через стандартное HTTP-соединение, но socket.io - это немного другой зверь.

Тодзи
источник
3
Незначительный касательный, но console.cat (socket), возможно, помог бы, если бы рекурсивно выгружал все в объекте сокета на консоль
izb
4
@izb Хороший замечание, но console.dir(socket)может быть это то, что вы имели в виду
LanguagesNamedAfterCofee

Ответы:

160

Хорошо, начиная с версии 0.7.7 это доступно, но не так, как описывает lubar. В итоге мне пришлось проанализировать некоторые журналы фиксации на git hub, чтобы понять это, но следующий код действительно работает для меня сейчас:

var io = require('socket.io').listen(server);

io.sockets.on('connection', function (socket) {
  var address = socket.handshake.address;
  console.log('New connection from ' + address.address + ':' + address.port);
});
Тодзи
источник
5
Гм ... потому что у него .connection.remoteAddress, а у меня .handshake.address?
Toji
2
@GarciadelCastillo, вероятно, вы за прокси. попробуйте это: stackoverflow.com/a/11187053/971459
Самсон,
4
Не работает в v1.0 - он просто записывает для меня адрес хоста.
Iest
1
По версии 1.3.7, это возвращается::ffff:127.0.0.1
dmr07
3
socket.request.connection.remoteAddressдля версии 1.x
Лукас Лисис
72

для 1.0.4:

io.sockets.on('connection', function (socket) {
  var socketId = socket.id;
  var clientIp = socket.request.connection.remoteAddress;

  console.log(clientIp);
});
flatroze
источник
Откуда вы взяли информацию? Я думал, что прочитал всю документацию по socket.io и не увидел этого. Он отлично сработал для решения моих проблем, подобных OP.
MikeB
1
Просто сокет console.log для просмотра всей доступной информации, я считаю, что он постоянно меняется, потому что не документирован.
Pez Cuckow
6
В v1.2.1, socket.request.connection.remoteAddressи socket.request.connection.remotePortработа для меня. Однако при попытке я не увидел ни одного из этих свойств в списке: console.log(util.inspect(socket.request.connection, {showHidden: true, colors: true})); Почему бы и нет?
Джеффри ЛеКурс
1
Также работает в 1.3.4. Спасибо
lima_fil
3
По версии 1.3.7, это возвращается::ffff:127.0.0.1
dmr07
46

Если вы используете другой сервер в качестве обратного прокси-сервера, все упомянутые поля будут содержать localhost. Самый простой обходной путь - добавить заголовки для IP / порта на прокси-сервере.

Пример для nginx: добавьте это после proxy_pass:

proxy_set_header  X-Real-IP $remote_addr;
proxy_set_header  X-Real-Port $remote_port;

Это сделает заголовки доступными на сервере узла socket.io:

var ip = socket.handshake.headers["x-real-ip"];
var port = socket.handshake.headers["x-real-port"];

Обратите внимание, что заголовок внутренне преобразован в нижний регистр.

Если вы подключаете сервер узла напрямую к клиенту,

var ip = socket.conn.remoteAddress;

у меня работает с socket.io версии 1.4.6.

zuim
источник
5
Это лучшее решение, другие ответы не работают, если nodejs находится за прокси-сервером
Alfredo Gt
2
@zuim Вы, сударь, мой герой!
Flavio
20

Для последней версии socket.io используйте

socket.request.connection.remoteAddress

Например:

var socket = io.listen(server);
socket.on('connection', function (client) {
  var client_ip_address = socket.request.connection.remoteAddress;
}

помните, что приведенный ниже код возвращает IP-адрес сервера, а не IP-адрес клиента.

var address = socket.handshake.address;
console.log('New connection from ' + address.address + ':' + address.port);
SlyBeaver
источник
2
я собирался попробовать этот код рукопожатия, спасибо, что указали, что это бесполезно !!
RozzA
1
Какая версия подразумевается под "последней версией socket.io"? Укажите конкретную версию.
Аксели Пален
Последнее на июль 2014 года
SlyBeaver
8

Используя последнюю 1.0.6версию Socket.IOи развернутое приложение Heroku, я получаю клиент IPи portиспользую его headersв socket handshake:

var socketio = require('socket.io').listen(server);

socketio.on('connection', function(socket) {

  var sHeaders = socket.handshake.headers;
  console.info('[%s:%s] CONNECT', sHeaders['x-forwarded-for'], sHeaders['x-forwarded-port']);

}
Бальтазар
источник
6

Начиная с socket.io 1.1.0, я использую:

io.on('connection', function (socket) {
  console.log('connection :', socket.request.connection._peername);
  // connection : { address: '192.168.1.86', family: 'IPv4', port: 52837 }
}

Изменить : обратите внимание, что это не часть официального API, и поэтому не гарантируется его работа в будущих выпусках socket.io.

Также см. Соответствующую ссылку: проблема engine.io

Nha
источник
1
Подтверждено также с 1.3.3.
Codesleuth
@Rachael @ Codesleuth Спасибо за подтверждение версий, очень признательны. Я получаю несколько голосов, так что я думаю, это все еще в силе, но я не проверял себя.
nha
6

Версия 0.7.7 Socket.IO теперь утверждает, что возвращает IP-адрес клиента. Я добился успеха с:

var socket = io.listen(server);
socket.on('connection', function (client) {
  var ip_address = client.connection.remoteAddress;
}
Lubar
источник
2
его client.conn.remoteAddress; в более новых версиях.
Муджтаба Кабли
4

Это похоже на работу:

var io = require('socket.io').listen(80);
io.sockets.on('connection', function (socket) {
  var endpoint = socket.manager.handshaken[socket.id].address;
  console.log('Client connected from: ' + endpoint.address + ":" + endpoint.port);
});
Роберт Ларсен
источник
1
Это всегда возвращается 127.0.0.1для меня, а не для IP-адреса клиента (node.js работает на удаленном сервере).
Дэниел В.
попробуйте socket.request.connection.remoteAddress
Лукас Лисис
Укажите версию Socket.io, которую вы использовали.
Аксели Пален
4

Я обнаружил, что в socket.handshake.headers есть перенаправленный адрес, который не отображается на моем локальном компьютере. И мне удалось получить удаленный адрес, используя:

socket.handshake.headers['x-forwarded-for']

Это на стороне сервера, а не на стороне клиента.

Ufb007
источник
1
Все остальное, что я пробовал, вернулось, ::ffff:127.0.0.1но это дало мне настоящий IP
Стивен Потховен
люблю тебя, все остальные ответы дают мне loopback ip, работает только этот заголовок!
datdinhquoc
Это решение для последней версии [2.2.0]. Все остальное вернуло мне ip сервера.
Абдул Садик Ялчин
3

Из чтения исходного кода socket.io похоже, что метод "listen" принимает аргументы (server, options, fn), и если "server" является экземпляром сервера HTTP / S, он просто обернет его для вас.

Таким образом, вы могли бы предположительно предоставить ему пустой сервер, который прослушивает событие «соединение» и обрабатывает удаленный адрес сокета; однако все может быть очень сложно, если вам нужно связать этот адрес с реальным объектом socket.io Socket.

var http = require('http')
  , io = require('socket.io');
io.listen(new http.Server().on('connection', function(sock) {
  console.log('Client connected from: ' + sock.remoteAddress);
}).listen(80));

Возможно, будет проще отправить патч на socket.io, в котором их собственный объект Socket расширен с помощью свойства remoteAddress, назначенного во время соединения ...

maerics
источник
Этот патч скорее всего , будет включена в следующий релиз github.com/LearnBoost/Socket.IO-node/pull/286
MAK
3

Очень просто. Сначала положил

io.sockets.on('connection', function (socket) {

console.log(socket);

Вы увидите все поля сокета. затем используйте CTRL + F и найдите адрес слова. Наконец, когда вы найдете поле remoteAddress, используйте точки для фильтрации данных. в моем случае это

console.log(socket.conn.remoteAddress);
geniant
источник
Сегодня нашел такое же решение в похожем деле!
Filippo1980
Это не дает IP-адрес конечной точки клиента. В моем случае он просто возвращает IP-адрес обратного прокси-сервера.
Аксели Пален
3

В socket.io 2.0 : вы можете использовать:

socket.conn.transport.socket._socket.remoteAddress

работает с transports: ['websocket']

Крис'
источник
3

Это работает для последней версии 2.3.0 :

io.on('connection', socket => {
   const ip = socket.handshake.headers[x-forwarded-for] || socket.conn.remoteAddress.split(":")[3];
   console.log(ip);
});
Диого Капела
источник
2

в socket.io1.3.4 у вас есть следующие возможности.

socket.handshake.address,

socket.conn.remoteAddress или

socket.request.client._peername.address

Яки Кляйн
источник
2

В версии v2.3.0

эта работа для меня:

socket.handshake.headers['x-forwarded-for'].split(',')[0]
Rizuwan Intercooler
источник
1

использование socket.request.connection.remoteAddress

DuckHunter
источник
4
По версии 1.3.7это возвращается::ffff:127.0.0.1
dmr07
1

Последняя версия работает с:

console.log(socket.handshake.address);
Khanasyubighi
источник
5
По версии 1.3.7, это возвращается::ffff:127.0.0.1
dmr07
аналогичный 1.4.8 :: ffff: 10.0.0.7
Xin
1
@ dmr07 это версия IPv6. Вы можете принудительно настроить IPv4, заставив http-сервер слушать 0.0.0.0. Связанный: stackoverflow.com/a/37378670/5138796
darrachequesne
вы можете сделать console.log (socket.handshake.address.substring (7)), он просто напечатает ip 127.0.0.1
node_man
1

Добро пожаловать в 2019 год, когда машинопись постепенно захватывает мир. Другие ответы все еще в силе. Однако я просто хотел показать вам, как вы можете настроить это в типизированной среде.

Если вы еще этого не сделали. Вы должны сначала установить некоторую зависимость (например , из командной строки: npm install <dependency-goes-here> --save-dev)

  "devDependencies": {
    ...
    "@types/express": "^4.17.2",
    ...
    "@types/socket.io": "^2.1.4",
    "@types/socket.io-client": "^1.4.32",
    ...
    "ts-node": "^8.4.1",
    "typescript": "^3.6.4"
  }

Я определил импорт, используя импорт ES6 (который вы должны tsconfig.jsonсначала включить в своем файле).

import * as SocketIO from "socket.io";
import * as http from "http";
import * as https from "https";
import * as express from "express";

Поскольку я использую машинописный текст, у меня теперь есть полный набор текста для всего, что я делаю с этими объектами.

Итак, очевидно, для начала вам понадобится http-сервер:

const handler = express();

const httpServer = (useHttps) ?
  https.createServer(serverOptions, handler) :
  http.createServer(handler);

Думаю, ты уже все это сделал. И вы, наверное, уже добавили в него socket io:

const io = SocketIO(httpServer);
httpServer.listen(port, () => console.log("listening") );
io.on('connection', (socket) => onSocketIoConnection(socket));

Затем, для обработки новых соединений socket-io, вы можете указать SocketIO.Socketтип в его параметре.

function onSocketIoConnection(socket: SocketIO.Socket) {      
  // I usually create a custom kind of session object here.
  // then I pass this session object to the onMessage and onDisconnect methods.

  socket.on('message', (msg) => onMessage(...));
  socket.once('disconnect', (reason) => onDisconnect(...));
}

И наконец, поскольку теперь у нас есть полная типизация, мы можем легко получить ip из нашего сокета, не догадываясь:

const ip = socket.conn.remoteAddress;
console.log(`client ip: ${ip}`);
bvdb
источник
-1

В 1.3.5:

var clientIP = socket.handshake.headers.host;
Системный вызов
источник
5
Что касается версии 1.3.7, это возвращает URL-адрес страницы, а не IP-
адрес