【问题标题】:Persisting a cookie based session over node-http-proxy通过 node-http-proxy 持久化基于 cookie 的会话
【发布时间】: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);

【问题讨论】:

    标签: javascript node.js proxy express node-http-proxy


    【解决方案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 没有传递给客户端。 解决方案:

        1. 从代理响应中获取 cookie
        2. 在代理请求中设置,数值稍作修改
        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];
                  }
                }
        
            }
          }
        }
        

        【讨论】:

          猜你喜欢
          • 2015-11-05
          • 1970-01-01
          • 2013-04-28
          • 2016-04-24
          • 2013-03-06
          • 1970-01-01
          • 2016-08-10
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多