You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在http-proxy中拦截WebSocket握手请求获取认证数据

解决方案:拦截WebSocket握手请求并访问认证数据

你的代码框架已接近目标,只需调整几个关键点就能实现需求:

1. 直接访问认证中间件数据

WebSocket握手阶段触发的proxyReqWs事件中,req参数就是经过Express中间件处理后的请求对象,你可以直接从中读取认证相关数据(比如req.user或自定义的认证字段):

proxy.on('proxyReqWs', (proxyReq, req, socket, options, head) => {
    // 从req对象获取认证中间件注入的数据
    const authData = req.user; // 替换为你实际的认证字段名
    console.log('WebSocket握手请求的认证信息:', authData);
    
    // 仅读取数据,不修改请求,满足你的需求
});

2. 避免重复绑定事件监听器

不要在app.use('/socket.io')回调内部绑定proxyRes和error事件,否则每次请求都会新增监听器,导致内存泄漏或重复执行逻辑。应将这些监听器移到全局作用域,只绑定一次:

// 全局绑定proxy事件,仅执行一次
proxy.on('proxyRes', function (proxyRes, req, res) {
    // 处理REST请求的响应逻辑
});

proxy.on('error', function (err, req, res) {
    console.error('代理错误:', err);
});

app.use('/socket.io', function (req, res) {
    proxy.web(req, res, { target: { host: address.host, port: address.port, path: '/socket.io' } });
});

3. 确认WebSocket代理逻辑正确性

你的server.on('upgrade')回调已正确触发WebSocket代理,proxy.ws方法会自动完成握手转发,且proxyReqWs仅在握手阶段触发一次,不会干扰后续的WebSocket消息收发,完全符合你的要求。

完整修正后的代码

var app = express();
const fs = require('fs');
var https = require('https');
var httpProxy = require('http-proxy');
const credentials = { key: fs.readFileSync("localhost.key"), cert: fs.readFileSync("localhost.cert") };

var proxy = httpProxy.createProxyServer({ ws: true });
var server = https.createServer(credentials, app).listen(8080);

// 全局绑定proxy事件,避免重复绑定
proxy.on('proxyRes', function (proxyRes, req, res) {
    // 处理REST请求的响应逻辑
});

proxy.on('error', function (err, req, res) {
    console.error('代理错误:', err);
});

// 拦截WebSocket握手请求,访问认证数据
proxy.on('proxyReqWs', (proxyReq, req, socket, options, head) => {
    // 从req对象获取认证中间件注入的数据
    const authData = req.authData; // 替换成你实际的认证字段名
    console.log('WebSocket握手请求的认证信息:', authData);
    
    // 仅读取数据,不修改请求
});

app.use('/socket.io', function (req, res) {
    proxy.web(req, res, { target: { host: address.host, port: address.port, path: '/socket.io' } });
});

server.on('upgrade', function (req, socket, head) {
    console.log("升级为WebSocket连接");
    proxy.ws(req, socket, head, { target: { host: address.host, port: address.port, path: '/socket.io' } });
});

关键说明

  • proxyReqWs事件仅在WebSocket握手发起时触发一次,不会影响连接建立后的消息传输。
  • 认证中间件处理后的所有数据都保存在req对象中,直接访问即可(WebSocket握手是GET请求,无请求体)。
  • 确保认证中间件在app.use('/socket.io')之前挂载,保证req对象进入代理逻辑前已包含认证数据。

内容的提问来源于stack exchange,提问作者Areej Fatimah

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 06:20:52