簡體   English   中英

在 socket.io 中獲取客戶端的 IP 地址

[英]Get the client's IP address in socket.io

在 Node.js 服務器中使用 socket.IO 時,是否有一種簡單的方法來獲取傳入連接的 IP 地址? 我知道您可以從標准 HTTP 連接獲取它,但 socket.io 有點不同。

好的,從 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);
});

對於 1.0.4:

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

  console.log(clientIp);
});

如果您使用其他服務器作為反向代理,則所有提到的字段都將包含 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。

對於最新的 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);

使用最新的1.0.6Socket.IO並將我的應用程序部署在Heroku ,我使用headers獲取客戶端IPportsocket 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']);

}

這適用於2.3.0版本:

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

從 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 issue

Socket.IO 的 0.7.7 版本現在聲稱返回客戶端的 IP 地址。 我在以下方面取得了成功:

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

好簡單。 先放

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

console.log(socket);

您將看到套接字的所有字段。 然后使用 CTRL+F 並搜索單詞地址。 最后,當您找到字段 remoteAddress 時,使用點來過濾數據。 就我而言,它是

console.log(socket.conn.remoteAddress);

我發現在 socket.handshake.headers 中有一個轉發地址,它沒有出現在我的本地機器上。 我能夠使用以下方法獲取遠程地址:

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

這是在服務器端而不是客戶端。

這似乎有效:

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

在 socket.io 2.0 中:您可以使用:

socket.conn.transport.socket._socket.remoteAddress

適用於transports: ['websocket']

從閱讀 socket.io 源代碼來看,“listen”方法看起來像接受參數(服務器、選項、fn),如果“服務器”是 HTTP/S 服務器的一個實例,它會簡單地為你包裝它。

所以你大概可以給它一個空服務器,它監聽 'connection' 事件並處理套接字 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.io 提交補丁可能更容易,其中他們自己的 Socket 對象使用在連接時分配的 remoteAddress 屬性進行擴展...

socket.io 1.3.4 上,您有以下可能性。

socket.handshake.address ,

socket.conn.remoteAddress

socket.request.client._peername.address

v2.3.0版本中

這對我有用:

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

歡迎來到 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";

因為我使用打字稿,所以我現在可以完全打字,對我對這些對象所做的一切。

所以,很明顯,首先你需要一個 http 服務器:

const handler = express();

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

我想你已經做到了這一切。 您可能已經向其中添加了 socket 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}`);

使用socket.request.connection.remoteAddress

最新版本適用於:

console.log(socket.handshake.address);

以下是獲取客戶端 IP 地址 (v 3.1.0) 的方法:


// Current Client
const ip = socket.handshake.headers["x-forwarded-for"].split(",")[1].toString().substring(1, this.length);
// Server 
const ip2 = socket.handshake.headers["x-forwarded-for"].split(",")[0].toString();

只是為了檢查它是否有效,請轉到geoplugin.net/json.gsp?ip=只需確保在鏈接中切換 ip。 完成后,它應該為您提供客戶端的准確位置,這意味着它有效。

我瀏覽了博客文章,甚至人們對這個問題的回答。

我嘗試了socket.handshake.address並且它工作了,但以::ffff為前綴

我不得不使用正則表達式來刪除它。

這適用於4.0.1

socket.conn.remoteAddress

對於我的情況

我改變我的

app.configure(socketio)

app.configure(socketio(function(io) {
 io.use(function (socket, next) {
   socket.feathers.clientIP = socket.request.connection.remoteAddress;
   next();
 });
}));

我可以像這樣獲得ip

function checkIP() {
  return async context => {
    context.data.clientIP = context.params.clientIP
  }
}

module.exports = {
  before: {
    all: [],
    find: [
      checkIp()
    ]}
  }

在 1.3.5 中:

var clientIP = socket.handshake.headers.host;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM