通过 node-http-proxy 持久化基于 cookie 的会话
Posted
技术标签:
【中文标题】通过 node-http-proxy 持久化基于 cookie 的会话【英文标题】:Persisting a cookie based session over node-http-proxy 【发布时间】:2012-05-04 16:21:48 【问题描述】:我有一个简单的基于 Express 的 Node.js Web 服务器,用于开发 javascript 应用程序。我将服务器设置为使用 node-http-proxy 来代理应用程序向在不同域和端口上运行的 Jetty 服务器发出的 API 请求。在我开始遇到会话管理问题之前,此设置一直运行良好。
在认证后,应用服务器返回一个带有认证令牌的 cookie,代表服务器会话。当我从我的文件系统 (file://) 运行 JS 应用程序时,我可以看到一旦客户端收到 cookie,它就会在所有后续 API 请求中发送。当我在节点服务器上运行 JS 应用程序并通过 node-http-proxy (RoutingProxy) 代理 API 调用时,请求标头从不包含 cookie。
我需要手动处理一些事情以通过代理支持这种类型的会话持久性吗?我一直在研究 node-http-proxy 代码,但这有点过头了,因为我是 Node 新手。
https://gist.github.com/2475547 或:
var express = require('express'),
routingProxy = require('http-proxy').RoutingProxy(),
app = express.createServer();
var apiVersion = 1.0,
apiHost = my.host.com,
apiPort = 8080;
function apiProxy(pattern, host, port)
return function(req, res, next)
if (req.url.match(pattern))
routingProxy.proxyRequest(req, res, host: host, port: port);
else
next();
app.configure(function ()
// API proxy middleware
app.use(apiProxy(new RegExp('\/' + apiVersion + '\/.*'), apiHost, apiPort));
// Static content middleware
app.use(express.methodOverride());
app.use(express.bodyParser());
app.use(express.static(__dirname));
app.use(express.errorHandler(
dumpExceptions: true,
showStack: true
));
app.use(app.router);
);
app.listen(3000);
【问题讨论】:
【参考方案1】:我通过手动查看响应来完成您的要求,查看它是否是 set-cookie,剪掉 JSESSSIONID,将其存储在变量中,并将其作为标头传递给所有后续请求。这样反向代理就充当了 cookie。
on('proxyReq', function(proxyReq) proxyReq.setHeader('cookie', 'sessionid=' + cookieSnippedValue)
【讨论】:
【参考方案2】:嗨 @tomswift 你的本地服务器是否运行在 http 协议上,但是从远程服务器接收的会话 cookie 带有 Secure;
像:
'set-cookie':
[ 'JSESSIONID=COOKIEWITHSECURE98123; Path=/;HttpOnly;Secure;']
如果是这样,在本地服务器响应客户端之前,从原始响应(从远程服务器到本地服务器的响应)标头中提取 set-cookie
,删除 Secure;
并将其余部分放入代理响应(从本地服务器到客户端的响应)标头,例如:
'set-cookie':
[ 'JSESSIONID=COOKIEWITHSECURE98123; Path=/;HttpOnly;']
然后客户端将自动获取会话cookie。
希望对你有所帮助。
【讨论】:
感谢您提及此@Halt 删除secure
标志也解决了我与 JSESSIONID 相关的问题
删除“安全”标志时要小心。这意味着 cookie 将通过不安全的连接发送,并且可能会暴露给数据包嗅探器,从而可能泄露用户的登录凭据或敏感的会话信息!【参考方案3】:
理想情况下,代理的工作只是将请求转发到目的地,并且不应该剥离像 cookie 这样的关键标头,但如果是这样,我认为您应该在 https://github.com/nodejitsu/node-http-proxy/issues 处针对它们提出问题。
你还说请求头从不包含cookie,客户端是否可能从未收到它?
【讨论】:
我已在 Web Inspector 中确认客户端收到了“set-cookie”标头。您可以看到交易here。在这种情况下,请求 cookie 是由 Express 的 cookieParser 生成的,我试图用它来支持会话,但它似乎总是做自己的事情。 在 GitHub 中打开了一个问题,因为我努力尝试从代理服务器的响应中获取 cookie 并手动支持会话:github.com/nodejitsu/node-http-proxy/issues/236【参考方案4】:我找到了一种通过分叉和修改 node-http-proxy 来实现这一点的方法。它服务于我目前的目的,即开发环境。对于任何形式的严肃考虑,都需要将其充实为更合理的解决方案。
详情可参考我在GitHub提交的issue:https://github.com/nodejitsu/node-http-proxy/issues/236#issuecomment-5334457
我希望对此解决方案有一些意见,尤其是如果我完全走错了方向。
【讨论】:
【参考方案5】:我有类似的问题,cookie 没有传递给客户端。 解决方案:
-
从代理响应中获取 cookie
在代理请求中设置,数值稍作修改
let cookie;
const webpackConfig =
proxy:
'/api':
...
onProxyReq: (proxyReq) =>
if(cookie)
proxyReq.setHeader('Cookie', cookie);
,
onProxyRes: (proxyRes) =>
const sc = proxyRes.headers['set-cookie'];
const raw = sc.filter(s => s.startsWith('JSESSIONID'));
if(raw.length)
cookie = raw[0].split(';')[0];
【讨论】:
以上是关于通过 node-http-proxy 持久化基于 cookie 的会话的主要内容,如果未能解决你的问题,请参考以下文章
使用node-http-proxy POST,PUT请求报‘socket hang up’错误
使用 node-http-proxy 从 NodeJS 到 Apache 的反向代理不起作用