Uzyskaj adres IP klienta w socket.io


133

Używając socket.IO na serwerze Node.js, czy istnieje łatwy sposób na uzyskanie adresu IP połączenia przychodzącego? Wiem, że możesz to uzyskać ze standardowego połączenia HTTP, ale socket.io to trochę inna bestia.


3
Nieznaczna styczna, ale console.cat (gniazdo) mogła prawdopodobnie pomóc, rekurencyjnie zrzucając wszystko z obiektu gniazda na konsolę
izb

4
@izb Słuszna uwaga, ale console.dir(socket)może o to chodziło
LanguagesNamedAfterCofee

Odpowiedzi:


161

OK, od wersji 0.7.7 jest to dostępne, ale nie w sposób opisany przez Lubar. Skończyło się na tym, że musiałem przeanalizować niektóre dzienniki zatwierdzeń w git hub, aby to zrozumieć, ale następujący kod faktycznie teraz działa dla mnie:

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
Um ... ponieważ jego to .connection.remoteAddress, a mój to .handshake.address?
Toji,

2
@GarciadelCastillo prawdopodobnie znajdujesz się za proxy. spróbuj tego: stackoverflow.com/a/11187053/971459
Samson,

4
Nie działa w wersji 1.0 - po prostu loguje dla mnie adres hosta.
Ostatni

1
Począwszy od wersji 1.3.7, to powraca::ffff:127.0.0.1
dmr07

3
socket.request.connection.remoteAddressdla wersji 1.x
Lukas Liesis

73

dla 1.0.4:

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

  console.log(clientIp);
});

Skąd masz informacje? Myślałem, że przeczytałem wszystkie dokumenty dotyczące socket.io i nie widziałem tego. Zadziałało idealnie, aby rozwiązać moje problemy podobne do OP.
MikeB

1
Wystarczy gniazdo console.log, aby wyświetlić wszystkie dostępne informacje. Myślę, że to się zmienia, ponieważ nie jest udokumentowane.
Pez Cuckow

6
W wersji 1.2.1 socket.request.connection.remoteAddressi socket.request.connection.remotePortpracuj dla mnie. Jednak gdy próbowałem, nie widziałem żadnej z tych właściwości: console.log(util.inspect(socket.request.connection, {showHidden: true, colors: true})); Dlaczego nie?
Jeffrey LeCours

1
Działa również w 1.3.4. Dzięki
lima_fil,

3
Od wersji 1.3.7zwraca to::ffff:127.0.0.1
dmr07

50

Jeśli używasz innego serwera jako zwrotnego proxy, wszystkie wymienione pola będą zawierać localhost. Najłatwiejszym sposobem obejścia tego problemu jest dodanie nagłówków adresu IP / portu na serwerze proxy.

Przykład dla nginx: dodaj to po proxy_pass:

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

Spowoduje to udostępnienie nagłówków na serwerze węzła socket.io:

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

Zauważ, że nagłówek jest wewnętrznie konwertowany na małe litery.

Jeśli łączysz serwer węzła bezpośrednio z klientem,

var ip = socket.conn.remoteAddress;

działa z socket.io w wersji 1.4.6 dla mnie.


5
To jest najlepsze rozwiązanie, inne odpowiedzi nie działają, jeśli nodejs jest za proxy
Alfredo Gt

2
@zuim Ty panie, jesteś moim bohaterem!
Flavio

20

Aby uzyskać najnowszą wersję socket.io, użyj

socket.request.connection.remoteAddress

Na przykład:

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

uważaj, poniższy kod zwraca adres IP serwera, a nie klienta

var address = socket.handshake.address;
console.log('New connection from ' + address.address + ':' + address.port);

2
właśnie miałem wypróbować ten kod uścisku dłoni, dziękuję za wskazanie, że jest bezużyteczny !!
RozzA

1
Jaką wersję rozumie się przez „ostatnią wersję socket.io”? Proszę podać konkretną wersję.
Akseli Palén

Najnowsze na lipiec 2014
SlyBeaver

8

Korzystając z najnowszej 1.0.6wersji Socket.IOi mam wdrożoną aplikację Heroku, otrzymuję klienta IPi portużywam headersgo w 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

Od socket.io 1.1.0 używam:

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

Edycja : Zwróć uwagę, że nie jest to część oficjalnego interfejsu API, a zatem nie ma gwarancji, że będzie działać w przyszłych wydaniach socket.io.

Zobacz także ten odpowiedni link: problem z engine.io


1
Potwierdzone również w 1.3.3.
Codesleuth

@Rachael @ Codesleuth Dzięki za potwierdzenie wersji, jest to bardzo cenne. Dostaję kilka głosów za, więc myślę, że jest to nadal ważne, ale nie testowałem siebie.
nha

6

Wersja 0.7.7 Socket.IO twierdzi teraz, że zwraca adres IP klienta. Odniosłem sukces z:

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

2
jego client.conn.remoteAddress; w nowszych wersjach.
Mujtaba Kably

4

To wydaje się działać:

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
To zawsze zwraca 127.0.0.1za mnie, a nie adres IP klienta (node.js działa na serwerze zdalnym).
Daniel W.

spróbuj socket.request.connection.remoteAddress
Lukas Liesis

Podaj używaną wersję Socket.io.
Akseli Palén

4

Odkryłem, że w pliku socket.handshake.headers jest plik przekierowany adres, który nie pojawia się na moim komputerze lokalnym. I udało mi się uzyskać zdalny adres za pomocą:

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

Jest to po stronie serwera, a nie klienta.


1
Wszystko inne, czego próbowałem, wróciło, ::ffff:127.0.0.1ale to dało mi rzeczywisty adres IP
Steven Pothoven

kocham cię, wszystkie inne odpowiedzi dają mi pętlę ip, tylko ten nagłówek działa!
datdinhquoc

To jest rozwiązanie dla najnowszej wersji [2.2.0]. Wszystko inne zwróciło mi IP serwera.
Abdul Sadik Yalcin,

3

Po odczytaniu kodu źródłowego socket.io wygląda na to, że metoda „Listen” pobiera argumenty (serwer, opcje, fn) i jeśli „serwer” jest instancją serwera HTTP / S, po prostu ją za ciebie zapakuje.

Można więc przypuszczalnie dać mu pusty serwer, który nasłuchuje zdarzenia „connection” i obsługuje gniazdo remoteAddress; Jednak sytuacja może być bardzo trudna, jeśli trzeba skojarzyć ten adres z rzeczywistym obiektem gniazda socket.io.

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));

Może być łatwiejsze przesłanie poprawki do socket.io, w którym ich własny obiekt Socket jest rozszerzony o właściwość remoteAddress przypisaną w czasie połączenia ...


Ta poprawka najprawdopodobniej zostanie uwzględniona w następnym wydaniu github.com/LearnBoost/Socket.IO-node/pull/286
mak

3

Bardzo łatwe. Pierwsze włożenie

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

console.log(socket);

Zobaczysz wszystkie pola gniazda. następnie użyj CTRL + F i wyszukaj słowo adres. Wreszcie, gdy znajdziesz pole remoteAddress, użyj kropek do filtrowania danych. w moim przypadku tak

console.log(socket.conn.remoteAddress);

Dziś znalazłem to samo rozwiązanie w podobnej sprawie!
Filippo1980,

To nie daje adresu IP punktu końcowego klienta. W moim przypadku po prostu zwraca adres IP odwrotnego serwera proxy.
Akseli Palén

3

W socket.io 2.0 : możesz użyć:

socket.conn.transport.socket._socket.remoteAddress

pracuje z transports: ['websocket']


3

Działa to dla najnowszej wersji 2.3.0 :

io.on('connection', socket => {
   const ip = socket.handshake.headers[x-forwarded-for] || socket.conn.remoteAddress.split(":")[3];
   console.log(ip);
});

2

w socket.io1.3.4 masz następujące możliwości.

socket.handshake.address,

socket.conn.remoteAddress lub

socket.request.client._peername.address



1

posługiwać się socket.request.connection.remoteAddress


4
Począwszy od wersji 1.3.7, zwraca to::ffff:127.0.0.1
dmr07


1

Witamy w 2019 roku, kiedy maszynopis powoli przejmuje świat. Inne odpowiedzi są nadal całkowicie aktualne. Chciałem jednak tylko pokazać, jak można to ustawić w środowisku pisania.

Na wypadek, gdybyś jeszcze tego nie zrobił. Najpierw należy zainstalować pewne współzależności (czyli z linii poleceń: 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"
  }

Zdefiniowałem import za pomocą importu ES6 (który powinieneś najpierw włączyć w swoim tsconfig.jsonpliku).

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

Ponieważ używam maszynopisu, mam teraz pełne pisanie na wszystkim, co robię z tymi obiektami.

Więc oczywiście najpierw potrzebujesz serwera http:

const handler = express();

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

Chyba już to wszystko zrobiłeś. I pewnie już dodałeś do niego gniazdo io:

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

Następnie, w celu obsługi nowych połączeń typu socket-io, możesz umieścić SocketIO.Sockettyp w jego parametrze.

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(...));
}

I wreszcie, ponieważ mamy teraz pełne wpisywanie, możemy łatwo pobrać ip z naszego gniazda, bez zgadywania:

const ip = socket.conn.remoteAddress;
console.log(`client ip: ${ip}`);

-1

W 1.3.5:

var clientIP = socket.handshake.headers.host;

5
Od wersji 1.3.7zwraca to adres URL strony, a nie adres IP
dmr07
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.