Obtenez l'adresse IP du client dans socket.io

133

Lors de l'utilisation de socket.IO dans un serveur Node.js, existe-t-il un moyen simple d'obtenir l'adresse IP d'une connexion entrante? Je sais que vous pouvez l'obtenir à partir d'une connexion HTTP standard, mais socket.io est un peu une bête différente.

Toji
la source
3
Légère tangente, mais console.cat (socket) aurait peut-être aidé en vidant récursivement tout ce qui se trouve dans l'objet socket sur la console
izb
4
@izb Bon point, mais c'est console.dir(socket)peut-être ce que vous vouliez dire
LanguagesNamedAfterCofee

Réponses:

160

D'accord, à partir de la version 0.7.7, cela est disponible, mais pas de la manière décrite par Lubar. J'ai fini par devoir analyser certains journaux de validation sur git hub pour comprendre celui-ci, mais le code suivant fonctionne réellement pour moi maintenant:

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
la source
5
Euh ... parce que son est .connection.remoteAddress et le mien est .handshake.address?
Toji
2
@GarciadelCastillo vous êtes probablement derrière un proxy. essayez ceci: stackoverflow.com/a/11187053/971459
Samson
4
Ne fonctionne pas dans la v1.0 - il enregistre simplement l'adresse de l'hôte pour moi.
Iest
1
À partir de la version 1.3.7, cela renvoie::ffff:127.0.0.1
dmr07
3
socket.request.connection.remoteAddresspour la version 1.x
Lukas Liesis
72

pour 1.0.4:

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

  console.log(clientIp);
});
flatroze
la source
Où avez-vous obtenu les informations? Je pensais avoir lu tous les documents de socket.io et je ne l'ai pas vu. Cela a parfaitement fonctionné pour résoudre mes problèmes similaires à l'OP.
MikeB
1
Juste un socket console.log pour afficher toutes les informations disponibles, je pense que cela change constamment car il n'est pas documenté.
Pez Cuckow
6
Dans la v1.2.1, socket.request.connection.remoteAddresset socket.request.connection.remotePorttravaillez pour moi. Cependant, je n'ai vu aucune de ces propriétés répertoriées lorsque j'ai essayé: console.log(util.inspect(socket.request.connection, {showHidden: true, colors: true})); pourquoi pas?
Jeffrey LeCours
1
Fonctionne également en 1.3.4. Merci
lima_fil
3
À partir de la version 1.3.7, cela renvoie::ffff:127.0.0.1
dmr07
46

Si vous utilisez un autre serveur comme proxy inverse, tous les champs mentionnés contiendront localhost. La solution de contournement la plus simple consiste à ajouter des en-têtes pour ip / port dans le serveur proxy.

Exemple pour nginx: ajoutez ceci après votre proxy_pass:

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

Cela rendra les en-têtes disponibles dans le serveur de nœuds socket.io:

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

Notez que l'en-tête est converti en interne en minuscules.

Si vous connectez le serveur de nœuds directement au client,

var ip = socket.conn.remoteAddress;

fonctionne avec socket.io version 1.4.6 pour moi.

zuim
la source
5
C'est la meilleure solution, les autres réponses ne fonctionnent pas si nodejs est derrière un proxy
Alfredo Gt
2
@zuim Vous monsieur, êtes mon héros!
Flavio
20

Pour la dernière version de socket.io, utilisez

socket.request.connection.remoteAddress

Par exemple:

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

attention que le code ci-dessous renvoie l'IP du serveur, pas l'IP du client

var address = socket.handshake.address;
console.log('New connection from ' + address.address + ':' + address.port);
SlyBeaver
la source
2
J'étais sur le point d'essayer ce code de poignée de main, merci d'avoir souligné qu'il était inutile !!
RozzA
1
Quelle version est désignée par "dernière version socket.io"? Veuillez fournir une version spécifique.
Akseli Palén
Dernier pour juillet 2014
SlyBeaver
8

À l'aide de la dernière 1.0.6version de Socket.IOet sur laquelle mon application est déployée Heroku, j'obtiens le client IPet j'utilise portle headersdans 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
la source
6

Depuis socket.io 1.1.0, j'utilise:

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

Edit : Notez que cela ne fait pas partie de l'API officielle et qu'il n'est donc pas garanti de fonctionner dans les futures versions de socket.io.

Voir également ce lien pertinent: problème engine.io

nha
la source
1
Confirmé avec 1.3.3 également.
Codesleuth
@Rachael @ Codesleuth Merci pour la confirmation des versions, c'est très apprécié. Je reçois quelques upvotes donc je suppose que c'est toujours valable, mais je ne me suis pas testé.
nha
6

La version 0.7.7 de Socket.IO prétend désormais renvoyer l'adresse IP du client. J'ai eu du succès avec:

var socket = io.listen(server);
socket.on('connection', function (client) {
  var ip_address = client.connection.remoteAddress;
}
Lubar
la source
2
son client.conn.remoteAddress; dans les nouvelles versions.
Mujtaba Kably
4

Cela semble fonctionner:

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
la source
1
Cela revient toujours 127.0.0.1pour moi, pas l'adresse IP du client (node.js s'exécute sur un serveur distant).
Daniel W.
essayez socket.request.connection.remoteAddress
Lukas Liesis
Veuillez fournir la version de Socket.io que vous utilisiez.
Akseli Palén
4

J'ai trouvé que dans le socket.handshake.headers, il y a une adresse transmise qui n'apparaît pas sur ma machine locale. Et j'ai pu obtenir l'adresse distante en utilisant:

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

C'est du côté serveur et non du côté client.

Ufb007
la source
1
Tout le reste que j'ai essayé est revenu, ::ffff:127.0.0.1mais cela m'a donné l'IP réelle
Steven Pothoven
je t'aime, toutes les autres réponses me donnent l'IP de bouclage, seul cet en-tête fonctionne!
datdinhquoc
C'est la solution pour la dernière version [2.2.0]. Tout le reste m'a renvoyé l'IP du serveur.
Abdul Sadik Yalcin
3

En lisant le code source de socket.io, il semble que la méthode "listen" prend des arguments (serveur, options, fn) et si "server" est une instance d'un serveur HTTP / S, il l'enveloppera simplement pour vous.

Vous pouvez donc vraisemblablement lui donner un serveur vide qui écoute l'événement 'connection' et gère le socket remoteAddress; cependant, les choses peuvent être très difficiles si vous devez associer cette adresse à un objet socket.io réel.

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

Peut-être plus facile de soumettre un correctif à socket.io dans lequel leur propre objet Socket est étendu avec la propriété remoteAddress attribuée au moment de la connexion ...

maerics
la source
Ce patch sera probablement inclus dans la prochaine version github.com/LearnBoost/Socket.IO-node/pull/286
mak
3

Très facile. Première mise

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

console.log(socket);

Vous verrez tous les champs de socket. puis utilisez CTRL + F et recherchez l'adresse de mot. Enfin, lorsque vous trouvez le champ remoteAddress, utilisez des points pour filtrer les données. dans mon cas c'est

console.log(socket.conn.remoteAddress);
géniant
la source
Aujourd'hui j'ai trouvé la même solution dans une affaire similaire!
Filippo1980
Cela ne donne pas l'adresse IP du point de terminaison client. Dans mon cas, il renvoie simplement l'adresse IP du serveur proxy inverse.
Akseli Palén
3

Dans socket.io 2.0 : vous pouvez utiliser:

socket.conn.transport.socket._socket.remoteAddress

marche avec transports: ['websocket']

Chris '
la source
3

Cela fonctionne pour la dernière 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
la source
2

sur socket.io1.3.4 vous avez les possibilités suivantes.

socket.handshake.address,

socket.conn.remoteAddress ou

socket.request.client._peername.address

Yaki Klein
la source
2

Dans la version v2.3.0

ce travail pour moi:

socket.handshake.headers['x-forwarded-for'].split(',')[0]
Intercooler Rizuwan
la source
1

utilisation socket.request.connection.remoteAddress

Chasseur de canard
la source
4
À partir de la version 1.3.7, cela renvoie::ffff:127.0.0.1
dmr07
1

La dernière version fonctionne avec:

console.log(socket.handshake.address);
Khanasyubighi
la source
5
À partir de la version 1.3.7, cela renvoie::ffff:127.0.0.1
dmr07
similaire 1.4.8 :: ffff: 10.0.0.7
Xin
1
@ dmr07 c'est la version IPv6. Vous pouvez forcer l'IPv4 en faisant écouter le serveur http 0.0.0.0. En relation: stackoverflow.com/a/37378670/5138796
darrachequesne
vous pouvez faire console.log (socket.handshake.address.substring (7)) il affichera simplement l'ip 127.0.0.1
node_man
1

Bienvenue en 2019, où la dactylographie envahit lentement le monde. D'autres réponses sont toujours parfaitement valables. Cependant, je voulais juste vous montrer comment configurer cela dans un environnement typé.

Au cas où vous ne l'auriez pas encore fait. Vous devez d' abord installer quelques dépendances ( par exemple à partir de la ligne de commande: 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"
  }

J'ai défini les importations à l'aide des importations ES6 (que vous devez d'abord activer dans votre tsconfig.jsonfichier.)

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

Parce que j'utilise dactylographié, j'ai maintenant une saisie complète, sur tout ce que je fais avec ces objets.

Donc, évidemment, vous avez d'abord besoin d'un serveur http:

const handler = express();

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

Je suppose que vous avez déjà fait tout cela. Et vous y avez probablement déjà ajouté socket io:

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

Ensuite, pour la gestion des nouvelles connexions socket-io, vous pouvez mettre le SocketIO.Sockettype sur son paramètre.

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

Et puis enfin, comme nous avons maintenant une saisie complète, nous pouvons facilement récupérer l'ip de notre socket, sans deviner:

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

En 1.3.5:

var clientIP = socket.handshake.headers.host;
Appel système
la source
5
À partir de la version 1.3.7, cela renvoie l'URL de la page, pas l'ip
dmr07