socket.ioでクライアントのIPアドレスを取得する


132

Node.jsサーバーでsocket.IOを使用する場合、着信接続の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ですか?
東寺

2
@GarciadelCastilloあなたはおそらくプロキシの後ろにいます。これを試してください:stackoverflow.com/a/11187053/971459
Samson

4
v1.0では機能しません—ホストのアドレスを記録するだけです。
Iest、2014

1
バージョン現在1.3.7、これは次を返します::ffff:127.0.0.1
dmr07 2015年

3
socket.request.connection.remoteAddress1.xバージョンの場合
Lukas Liesis 2016年

71

1.0.4の場合:

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

  console.log(clientIp);
});

どこで情報を入手しましたか?私はsocket.ioのすべてのドキュメントを読んだと思っていて、これを見なかった。OPと同様に、私の問題を完全に解決しました。
MikeB 2014年

1
利用可能なすべての情報を表示するためのconsole.logソケットだけですが、文書化されていないため、変化し続けると思います。
Pez Cuckow 2014年

6
v1.2.1ではsocket.request.connection.remoteAddresssocket.request.connection.remotePort私のために働いています。ただし、試したときにこれらのプロパティのいずれも表示されconsole.log(util.inspect(socket.request.connection, {showHidden: true, colors: true})); ませんでした。なぜですか?
Jeffrey LeCours 2014

1
1.3.4でも動作します。ありがとう
lima_fil

3
バージョン現在1.3.7、これは次を返します::ffff:127.0.0.1
dmr07 2015年

46

他のサーバーをリバースプロキシとして使用する場合、上記のすべてのフィールドにlocalhostが含まれます。最も簡単な回避策は、プロキシサーバーでip / portのヘッダーを追加することです。

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で動作します。


5
これは最良のソリューションです。nodejsがプロキシの背後にある場合、他の回答は機能しません
Alfredo Gt

2
@zuimあなたは私のヒーローです!
フラビオ

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

2
役に立たないことを指摘してくれてありがとう、そのハンドシェイクのコードを試そうとしていた!!
RozzA 2014

1
「最新のsocket.ioバージョン」とはどのバージョンですか?特定のバージョンを指定してください。
AkseliPalén19年

2014年7月の最新
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の問題


1
1.3.3でも確認済み。
Codesleuth、2015

@Rachael @ Codesleuthバージョンの確認ありがとうございます。私はいくつかの賛成票を受け取っているので、これはまだ有効だと思いますが、私は自分でテストしていません。
nha

6

Socket.IOのバージョン0.7.7は、クライアントのIPアドレスを返すように要求します。私は成功しました:

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

2
そのclient.conn.remoteAddress; 新しいバージョンで。
Mujtaba Kably 2016年

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はリモートサーバーで実行されます)。
ダニエルW.

socket.request.connection.remoteAddressを試してください
Lukas Liesis

使用していたSocket.ioのバージョンを入力してください。
AkseliPalén19年

4

私は、socket.handshake.headers内に、ローカルマシンに表示されない転送先アドレスがあることを発見しました。そして、私は使用してリモートアドレスを取得することができました:

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

これはサーバー側であり、クライアント側ではありません。


1
私が試した他のすべてのものは返されました::ffff:127.0.0.1が、これは私に実際のIPを与えました
Steven Pothoven 2017

あなたを愛して、他のすべての回答者はループバックIPを私に与えます
datdinhquoc 2018年

これは最新バージョン[2.2.0]のソリューションです。他のすべては私のためにサーバーIPを返しました。
Abdul Sadik Yalcin

3

socket.ioソースコードを読み取ると、「listen」メソッドは引数(サーバー、オプション、fn)を受け取るように見え、「server」がHTTP / Sサーバーのインスタンスである場合は、単純にラップされます。

したがって、おそらく '接続'イベントをリッスンし、ソケットのremoteAddressを処理する空のサーバーを指定できます。ただし、そのアドレスを実際の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オブジェクトが接続時に割り当てられたremoteAddressプロパティで拡張されているsocket.ioにパッチを送信する方が簡単かもしれません...


このパッチは次のリリースに含まれる可能性が高いです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);

今日、私は同様の問題で同じ解決策を見つけました!
Filippo1980 16

これは、クライアントエンドポイントのIPを提供しません。私の場合、リバースプロキシサーバーのIPを返すだけです。
AkseliPalén19年

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




1

最新バージョンは以下で動作します:

console.log(socket.handshake.address);

5
バージョン現在1.3.7、これは次を返します::ffff:127.0.0.1
dmr07 2015年

同様の1.4.8 :: ffff:10.0.0.7
Xin

1
@ dmr07これはIPv6バージョンです。httpサーバーにリッスンさせることで、IPv4を強制できます0.0.0.0。関連:stackoverflow.com/a/37378670/5138796
darrachequesne '26 / 09/26

あなたはconsole.log(socket.handshake.address.substring(7))を行うことができますそれはちょうどIP 127.0.0.1を出力します
node_man

1

typescriptがゆっくりと世界を引き継ぐ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";

私はtypescriptを使用しているので、完全なタイピングができるようになりました。

したがって、明らかに、最初にhttpサーバーが必要です。

const handler = express();

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

あなたはすでにそれをすべてやったと思います。そしておそらくあなたはすでにそれにソケット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}`);

-1

1.3.5では:

var clientIP = socket.handshake.headers.host;

5
バージョン1.3.7以降、これはIPではなくページのURLを返します
dmr07 '18
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.