Ottieni l'indirizzo IP del client in socket.io


133

Quando si utilizza socket.IO in un server Node.js, esiste un modo semplice per ottenere l'indirizzo IP di una connessione in entrata? So che puoi ottenerlo da una connessione HTTP standard, ma socket.io è un po 'diverso.


3
Leggero tangente, ma console.cat (socket) avrebbe potuto essere d'aiuto scaricando in modo ricorsivo tutto ciò che era nell'oggetto socket sulla console
izb

4
@izb Buon punto, ma console.dir(socket)potrebbe essere quello che volevi dire
LanguagesNamedAfterCofee

Risposte:


160

Va bene, a partire da 0.7.7 questo è disponibile, ma non nel modo descritto da Lubar. Ho finito per dover analizzare alcuni log di commit sull'hub git per capirlo, ma il seguente codice funziona davvero per me ora:

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 ... perché il suo è .connection.remoteAddress e il mio è .handshake.address?
Toji,

2
@GarciadelCastillo probabilmente sei dietro un proxy. prova questo: stackoverflow.com/a/11187053/971459
Samson

4
Non funziona in v1.0 - registra semplicemente l'indirizzo dell'host per me.
Il

1
A partire dalla versione 1.3.7, questo ritorna::ffff:127.0.0.1
dmr07

3
socket.request.connection.remoteAddressper la versione 1.x
Lukas Liesis,

72

per 1.0.4:

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

  console.log(clientIp);
});

Dove hai preso le informazioni? Pensavo di aver letto tutti i documenti per socket.io e non l'ho visto. Ha funzionato perfettamente per risolvere i miei problemi in modo simile al PO.
MikeB,

1
Solo console.log socket per visualizzare tutte le informazioni disponibili, credo che continui a cambiare perché non è documentato.
Pez Cuckow,

6
In v1.2.1 socket.request.connection.remoteAddresse socket.request.connection.remotePortlavora per me. Tuttavia, non ho visto nessuna di queste proprietà elencate quando ho provato: console.log(util.inspect(socket.request.connection, {showHidden: true, colors: true})); Perché no?
Jeffrey LeCours,

1
Funziona anche in 1.3.4. Grazie
lima_fil,

3
A partire dalla versione 1.3.7, questo ritorna::ffff:127.0.0.1
dmr07

46

Se si utilizza un altro server come proxy inverso, tutti i campi menzionati conterranno localhost. La soluzione più semplice è aggiungere intestazioni per ip / porta nel server proxy.

Esempio per nginx: aggiungi questo dopo il tuo proxy_pass:

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

Ciò renderà le intestazioni disponibili nel server del nodo socket.io:

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

Si noti che l'intestazione viene convertita internamente in lettere minuscole.

Se si collega il server del nodo direttamente al client,

var ip = socket.conn.remoteAddress;

funziona con socket.io versione 1.4.6 per me.


5
Questa è la soluzione migliore, le altre risposte non funzionano se nodejs è dietro un proxy
Alfredo Gt

2
@zuim Signore, siete il mio eroe!
Flavio,

20

Per l'ultima versione di socket.io utilizzare

socket.request.connection.remoteAddress

Per esempio:

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

attenzione che il codice seguente restituisce l'IP del server, non l'IP del client

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

2
stavo per provare quel codice di stretta di mano, grazie per aver sottolineato che è inutile !!
Rozz,

1
Quale versione si intende per "ultima versione di socket.io"? Fornisci una versione specifica.
Akseli Palén

Ultime
novità

8

Utilizzando la 1.0.6versione più recente di Socket.IOe la mia app distribuita su Heroku, ottengo il client IPe portusando il 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']);

}

6

Da socket.io 1.1.0, utilizzo:

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

Modifica : si noti che questo non fa parte dell'API ufficiale e pertanto non funzionerà nelle versioni future di socket.io.

Vedi anche questo link pertinente: engine.io issue


1
Confermato anche con 1.3.3.
Codesleuth

@Rachael @ Codesleuth Grazie per la conferma delle versioni, è molto apprezzato. Ricevo alcuni voti quindi immagino che sia ancora valido, ma non mi sono testato.
nha

6

La versione 0.7.7 di Socket.IO ora afferma di restituire l'indirizzo IP del client. Ho avuto successo con:

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

2
relativo indirizzo client.conn.remote; nelle versioni più recenti.
Mujtaba Kably,

4

Questo sembra funzionare:

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
Questo ritorna sempre 127.0.0.1per me, non per l'IP del client (node.js viene eseguito sul server remoto).
Daniel W.

provare socket.request.connection.remoteAddress
Lukas Liesis il

Fornisci la versione di Socket.io che stavi utilizzando.
Akseli Palén

4

Ho scoperto che all'interno del socket.handshake.headers c'è un indirizzo inoltrato che non appare sul mio computer locale. E sono stato in grado di ottenere l'indirizzo remoto utilizzando:

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

Questo è sul lato server e non sul lato client.


1
Tutto il resto che ho provato è tornato, ::ffff:127.0.0.1ma questo mi ha dato l'IP reale
Steven Pothoven,

ti amo, tutte le altre risposte mi danno loopback ip, funziona solo questa intestazione!
datdinhquoc,

Questa è la soluzione per l'ultima versione [2.2.0]. Tutto il resto ha restituito l'ip del server per me.
Abdul Sadik Yalcin,

3

Dalla lettura del codice sorgente socket.io sembra che il metodo "Listen" prenda argomenti (server, opzioni, fn) e se "server" è un'istanza di un server HTTP / S, lo avvolgerà semplicemente per te.

Quindi potreste presumibilmente dargli un server vuoto che ascolta l'evento 'connection' e gestisce il socket remoteAddress; tuttavia, le cose potrebbero essere molto difficili se è necessario associare quell'indirizzo a un oggetto Socket socket.io effettivo.

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

Potrebbe essere più semplice inviare una patch a socket.io in cui il proprio oggetto Socket viene esteso con la proprietà remoteAddress assegnata al momento della connessione ...


Questa patch sarà probabilmente incluso nella prossima release github.com/LearnBoost/Socket.IO-node/pull/286
mak

3

Molto facile. In primo luogo

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

console.log(socket);

Vedrai tutti i campi del socket. quindi usa CTRL + F e cerca l'indirizzo della parola. Infine, quando trovi il campo remoteAddress usa i punti per filtrare i dati. nel mio caso lo è

console.log(socket.conn.remoteAddress);

Oggi ho trovato la stessa soluzione in una questione simile!
Filippo 1980,

Ciò non fornisce l'IP dell'endpoint client. Nel mio caso restituisce semplicemente l'IP del server proxy inverso.
Akseli Palén,

3

In socket.io 2.0 : puoi usare:

socket.conn.transport.socket._socket.remoteAddress

lavora con transports: ['websocket']


3

Funziona con l'ultima versione 2.3.0 :

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

2

su socket.io1.3.4 hai le seguenti possibilità.

socket.handshake.address,

socket.conn.remoteAddress o

socket.request.client._peername.address


2

Nella versione v2.3.0

questo lavoro per me:

socket.handshake.headers['x-forwarded-for'].split(',')[0]

1

uso socket.request.connection.remoteAddress


4
A partire dalla versione 1.3.7, questo ritorna::ffff:127.0.0.1
dmr07

1

L'ultima versione funziona con:

console.log(socket.handshake.address);

5
A partire dalla versione 1.3.7, questo ritorna::ffff:127.0.0.1
dmr07

simile 1.4.8 :: ffff: 10.0.0.7
Xin

1
@ dmr07 questa è la versione IPv6. È possibile forzare IPv4 facendo ascoltare il server http 0.0.0.0. Correlati: stackoverflow.com/a/37378670/5138796
darrachequesne

puoi fare console.log (socket.handshake.address.substring (7)) stamperà semplicemente l'ip 127.0.0.1
node_man

1

Benvenuto nel 2019, dove il dattiloscritto prende lentamente il sopravvento sul mondo. Altre risposte sono ancora perfettamente valide. Tuttavia, volevo solo mostrarti come è possibile configurarlo in un ambiente tipizzato.

Nel caso in cui non l'hai ancora fatto. Si dovrebbe prima installare alcune dipendenze (cioè dalla linea di comando: 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"
  }

Ho definito le importazioni usando le importazioni ES6 (che dovresti prima abilitare nel tuo tsconfig.jsonfile).

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

Poiché uso il dattiloscritto, ora ho la digitazione completa, su tutto ciò che faccio con questi oggetti.

Quindi, ovviamente, prima devi avere un server http:

const handler = express();

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

Immagino tu abbia già fatto tutto questo. E probabilmente hai già aggiunto socket io ad esso:

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

Successivamente, per la gestione di nuove connessioni socket-io, è possibile inserire il SocketIO.Sockettipo sul suo parametro.

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

E infine, poiché ora abbiamo la digitazione completa, possiamo facilmente recuperare l'ip dal nostro socket, senza indovinare:

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

-1

In 1.3.5:

var clientIP = socket.handshake.headers.host;

5
A partire dalla versione 1.3.7, questo restituisce l'URL della pagina, non ip
dmr07,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.