Node.js中express-http-proxy无法传递req.user至代理服务的解决方案
问题描述
在Node.js环境搭建了一个API网关,会校验请求头中的token,验证通过后设置req.user。代理代码如下:
proxy(host) { // call proxy middleware with request option return (req, res, next) => { let reqBodyEncoding; let reqAsBuffer = false; let parseReqBody = true; return default_proxy(host, { reqAsBuffer, reqBodyEncoding, parseReqBody, })(req, res, next); } }
现在被代理的服务无法获取到req.user,该如何解决?
解决方案
代理中间件不会自动转发req对象上的自定义属性(比如req.user),因为HTTP协议本身不携带这类自定义内存属性,必须通过HTTP标准传递方式(请求头、URL参数、请求体)把用户信息传给下游服务,以下是两种可行方案:
方案1:通过自定义请求头传递用户信息
修改代理代码,添加onProxyReq钩子,在发送代理请求前把req.user序列化后放到自定义请求头中:
proxy(host) { return (req, res, next) => { let reqBodyEncoding; let reqAsBuffer = false; let parseReqBody = true; return default_proxy(host, { reqAsBuffer, reqBodyEncoding, parseReqBody, // 代理请求发送前的钩子 onProxyReq: (proxyReq, req) => { if (req.user) { // 将用户信息序列化为JSON字符串,放到自定义请求头 proxyReq.setHeader('X-User-Info', JSON.stringify(req.user)); } } })(req, res, next); } }
然后在被代理的服务中,解析这个自定义请求头恢复req.user:
// 被代理服务的前置中间件 app.use((req, res, next) => { const userHeader = req.headers['x-user-info']; if (userHeader) { try { req.user = JSON.parse(userHeader); } catch (err) { console.error('解析用户信息失败:', err); } } next(); });
方案2:加密敏感用户信息(可选)
如果req.user包含敏感数据,建议对序列化后的字符串进行加密处理,避免在网络传输中泄露:
// 网关端加密 const crypto = require('crypto'); const secretKey = '你的加密密钥'; onProxyReq: (proxyReq, req) => { if (req.user) { const userStr = JSON.stringify(req.user); // 简单加密示例(实际可使用更安全的加密算法) const encrypted = crypto.createHmac('sha256', secretKey).update(userStr).digest('base64'); proxyReq.setHeader('X-User-Info', encrypted); } }
被代理服务端解密:
app.use((req, res, next) => { const userHeader = req.headers['x-user-info']; if (userHeader) { try { const decrypted = crypto.createHmac('sha256', secretKey).update(Buffer.from(userHeader, 'base64')).digest('utf8'); req.user = JSON.parse(decrypted); } catch (err) { console.error('解析用户信息失败:', err); } } next(); });
内容的提问来源于stack exchange,提问作者Code Guru
相关产品推荐
相关产品推荐

