Rufen Sie die IP-Adresse des Clients in socket.io ab

132

Gibt es bei Verwendung von socket.IO auf einem Node.js-Server eine einfache Möglichkeit, die IP-Adresse einer eingehenden Verbindung abzurufen? Ich weiß, dass Sie es von einer Standard-HTTP-Verbindung erhalten können, aber socket.io ist ein etwas anderes Biest.

Toji
quelle
3
Leichte Tangente, aber console.cat (Socket) hat möglicherweise geholfen, indem rekursiv alles im Socket-Objekt auf die Konsole
ausgegeben wurde
4
@izb Guter Punkt, aber console.dir(socket)könnte sein, was Sie meinten
LanguagesNamedAfterCofee

Antworten:

160

Okay, ab 0.7.7 ist dies verfügbar, aber nicht in der von lubar beschriebenen Weise. Am Ende musste ich einige Commit-Protokolle auf dem Git-Hub analysieren, um dies herauszufinden, aber der folgende Code funktioniert jetzt tatsächlich für mich:

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);
});
Toji
quelle
5
Ähm ... weil seine .connection.remoteAddress und meine .handshake.address ist?
Toji
2
@GarciadelCastillo Sie sind wahrscheinlich hinter einem Proxy. Versuchen Sie dies: stackoverflow.com/a/11187053/971459
Samson
4
Funktioniert nicht in Version 1.0 - es protokolliert nur die Adresse des Hosts für mich.
Iest
1
Ab Version 1.3.7kehrt dies zurück::ffff:127.0.0.1
dmr07
3
socket.request.connection.remoteAddressfür 1.x Version
Lukas Liesis
70

für 1.0.4:

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

  console.log(clientIp);
});
Flatroze
quelle
Woher hast du die Infos? Ich dachte, ich hätte alle Dokumente für socket.io gelesen und dies nicht gesehen. Es hat perfekt funktioniert, um meine Probleme ähnlich dem OP zu lösen.
MikeB
1
Nur console.log Socket, um alle verfügbaren Informationen anzuzeigen. Ich glaube, es ändert sich ständig, weil es nicht dokumentiert ist.
Pez Cuckow
6
In v1.2.1 socket.request.connection.remoteAddressund socket.request.connection.remotePortarbeite für mich. Beim Versuch habe ich jedoch keine dieser Eigenschaften aufgelistet: console.log(util.inspect(socket.request.connection, {showHidden: true, colors: true})); Warum nicht?
Jeffrey LeCours
1
Funktioniert auch in 1.3.4. Danke
lima_fil
3
Ab Version 1.3.7kehrt dies zurück::ffff:127.0.0.1
dmr07
46

Wenn Sie einen anderen Server als Reverse-Proxy verwenden, enthalten alle genannten Felder localhost. Die einfachste Problemumgehung besteht darin, Header für IP / Port auf dem Proxyserver hinzuzufügen.

Beispiel für Nginx: Fügen Sie dies nach Ihrem proxy_pass:

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

Dadurch werden die Header auf dem Knotenserver socket.io verfügbar:

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

Beachten Sie, dass der Header intern in Kleinbuchstaben konvertiert wird.

Wenn Sie den Knotenserver direkt mit dem Client verbinden,

var ip = socket.conn.remoteAddress;

funktioniert mit socket.io Version 1.4.6 für mich.

zuim
quelle
5
Dies ist die beste Lösung, die anderen Antworten funktionieren nicht, wenn nodejs hinter einem Proxy steht
Alfredo Gt
2
@zuim Sie Sir, sind mein Held!
Flavio
20

Für die neueste Version von socket.io verwenden

socket.request.connection.remoteAddress

Beispielsweise:

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

Beachten Sie, dass der folgende Code die IP des Servers und nicht die IP des Clients zurückgibt

var address = socket.handshake.address;
console.log('New connection from ' + address.address + ':' + address.port);
SlyBeaver
quelle
2
Ich wollte gerade diesen Handshake-Code ausprobieren, danke, dass du darauf hingewiesen hast, dass er nutzlos ist !!
RozzA
1
Welche Version ist mit "lastest socket.io version" gemeint? Bitte geben Sie eine bestimmte Version an.
Akseli Palén
Spätestens im Juli 2014
SlyBeaver
8

Mit der neuesten 1.0.6Version von Socket.IOund der Bereitstellung meiner App Herokuerhalte ich den Client IPund portverwende das headersin 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']);

}
Balthazar
quelle
6

Seit socket.io 1.1.0 verwende ich:

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

Bearbeiten : Beachten Sie, dass dies nicht Teil der offiziellen API ist und daher in zukünftigen Versionen von socket.io nicht garantiert funktioniert.

Siehe auch diesen relevanten Link: engine.io issue

nha
quelle
1
Bestätigt auch mit 1.3.3.
Codesleuth
@Rachael @ Codesleuth Vielen Dank für die Bestätigung für die Versionen, es wird sehr geschätzt. Ich bekomme ein paar Upvotes, also denke ich, dass dies immer noch gültig ist, aber ich habe mich nicht selbst getestet.
nha
6

Version 0.7.7 von Socket.IO behauptet nun, die IP-Adresse des Clients zurückzugeben. Ich hatte Erfolg mit:

var socket = io.listen(server);
socket.on('connection', function (client) {
  var ip_address = client.connection.remoteAddress;
}
lubar
quelle
2
seine client.conn.remoteAddress; in den neueren Versionen.
Mujtaba Kably
4

Das scheint zu funktionieren:

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);
});
Robert Larsen
quelle
1
Dies gibt 127.0.0.1für mich immer zurück , nicht die IP des Clients (node.js wird auf dem Remote-Server ausgeführt).
Daniel W.
versuchen Sie socket.request.connection.remoteAddress
Lukas Liesis
Bitte geben Sie die von Ihnen verwendete Socket.io-Version an.
Akseli Palén
4

Ich habe festgestellt, dass in den socket.handshake.headers eine weitergeleitete Adresse vorhanden ist, die auf meinem lokalen Computer nicht angezeigt wird . Und ich konnte die entfernte Adresse erhalten mit:

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

Dies ist auf der Serverseite und nicht auf der Clientseite.

Ufb007
quelle
1
Alles andere, was ich versuchte, kehrte zurück, ::ffff:127.0.0.1aber dies gab mir die tatsächliche IP
Steven Pothoven
Liebe dich, alle anderen Antworten geben mir Loopback-IP, nur dieser Header funktioniert!
Datdinhquoc
Dies ist die Lösung für die neueste Version [2.2.0]. Alles andere gab die Server-IP für mich zurück.
Abdul Sadik Yalcin
3

Beim Lesen des Quellcodes von socket.io sieht es so aus, als würde die Methode "listen" Argumente (Server, Optionen, fn) verwenden. Wenn "server" eine Instanz eines HTTP / S-Servers ist, wird sie einfach für Sie verpackt.

Sie könnten ihm also vermutlich einen leeren Server geben, der auf das Ereignis 'Verbindung' wartet und den Socket remoteAddress verarbeitet. Es kann jedoch sehr schwierig sein, diese Adresse einem tatsächlichen Socket.io-Socket-Objekt zuzuordnen.

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

Es könnte einfacher sein, einen Patch an socket.io zu senden, in dem das eigene Socket-Objekt um die zum Zeitpunkt der Verbindung zugewiesene Eigenschaft remoteAddress erweitert wird ...

Maerics
quelle
Dieser Patch wird höchstwahrscheinlich in der nächsten Version enthalten sein. Github.com/LearnBoost/Socket.IO-node/pull/286
mak
3

Sehr leicht. Zuerst setzen

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

console.log(socket);

Sie sehen alle Socket-Felder. Verwenden Sie dann STRG + F und suchen Sie die Wortadresse. Wenn Sie das Feld remoteAddress finden, verwenden Sie Punkte, um Daten zu filtern. in meinem Fall ist es

console.log(socket.conn.remoteAddress);
geniant
quelle
Heute habe ich die gleiche Lösung in einer ähnlichen Angelegenheit gefunden!
Filippo1980
Dies gibt nicht die IP des Client-Endpunkts an. In meinem Fall wird nur die IP des Reverse-Proxy-Servers zurückgegeben.
Akseli Palén
3

In socket.io 2.0 : können Sie verwenden:

socket.conn.transport.socket._socket.remoteAddress

arbeitet mit transports: ['websocket']

Chris '
quelle
3

Dies funktioniert für die neueste Version 2.3.0 :

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

Am socket.io1.3.4 haben Sie folgende Möglichkeiten.

socket.handshake.address,

socket.conn.remoteAddress oder

socket.request.client._peername.address

Yaki Klein
quelle
2

In Version v2.3.0

diese Arbeit für mich:

socket.handshake.headers['x-forwarded-for'].split(',')[0]
Rizuwan Ladeluftkühler
quelle
1

verwenden socket.request.connection.remoteAddress

DuckHunter
quelle
4
Ab Version 1.3.7kehrt dies zurück::ffff:127.0.0.1
dmr07
1

Neueste Version funktioniert mit:

console.log(socket.handshake.address);
Khanasyubighi
quelle
5
Ab Version 1.3.7kehrt dies zurück::ffff:127.0.0.1
dmr07
ähnlich 1.4.8 :: ffff: 10.0.0.7
Xin
1
@ dmr07 Dies ist die IPv6-Version. Sie können IPv4 erzwingen, indem Sie den http-Server abhören lassen 0.0.0.0. Siehe auch
darrachequesne
Sie können console.log (socket.handshake.address.substring (7)) tun, es wird nur die IP 127.0.0.1
node_man
1

Willkommen im Jahr 2019, wo Typoskript langsam die Welt erobert. Andere Antworten sind immer noch vollkommen gültig. Ich wollte Ihnen jedoch nur zeigen, wie Sie dies in einer typisierten Umgebung einrichten können.

Falls Sie es noch nicht getan haben. Sie sollten zunächst einige Abhängigkeiten installieren (dh von der Kommandozeile: 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"
  }

Ich habe die Importe mithilfe von ES6-Importen definiert (die Sie zuerst in Ihrer tsconfig.jsonDatei aktivieren sollten .)

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

Da ich Typoskript verwende, kann ich jetzt alles, was ich mit diesen Objekten mache, vollständig eingeben.

Natürlich benötigen Sie zuerst einen http-Server:

const handler = express();

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

Ich denke du hast das alles schon getan. Und Sie haben wahrscheinlich bereits Socket Io hinzugefügt:

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

Als Nächstes können Sie für die Behandlung neuer Socket-Io-Verbindungen den SocketIO.SocketTyp in seinen Parameter einfügen.

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

Und schließlich können wir, da wir jetzt vollständig tippen, die IP-Adresse problemlos aus unserem Socket abrufen, ohne zu raten:

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

In 1.3.5:

var clientIP = socket.handshake.headers.host;
Syscall
quelle
5
Ab Version 1.3.7gibt diese Seite URL zurück, nicht ip
dmr07