【问题标题】:Node.js / Connect Use Existing Connect.SIDNode.js / Connect 使用现有的 Connect.SID
【发布时间】:2013-11-25 07:19:56
【问题描述】:

我有鸡和蛋的问题。

我正在使用 Node.js HTTPServer 将 Web 请求路由到不同的 Node.js 工作者,具体取决于它们在请求标头中发送的 Connect.SID cookie。

我的每个 Node.js 工作人员都使用 Connect / Express 并在请求首次连接时分配 Connect.SID cookie。

问题

显然,如果请求的 Connect.SID 没有向 Node 的 该实例 注册,则 Connect 会分配一个 新 ID

所以,我有了一个新的 Connect.SID。我的 HTTP 代理记录 ID 12345 并将其路由到 worker #5。 Worker #5 将新 ID 56344 发送回浏览器。下一个浏览器请求 - HTTP 代理看到一个全新的 ID - 56344 - 记录它并发送给 Worker #6。工人 #6 看到新的 SID 并且......

Connect Session 中间件太……简单……

app.use(express.cookieParser());
app.use(express.session({ secret: "niceTry", cookie: { /* ... */ } }));

有没有办法将逻辑注入到新会话 ID 的分配中,以便在已有未注册但有效的 Connect.SID 时跳过它?

【问题讨论】:

    标签: node.js cookies http-proxy connect.js


    【解决方案1】:

    您是否考虑过在 Node/Express 中使用分布式会话管理(即 Redis)?这应该可以防止有效的会话固定问题。

    【讨论】:

    • 不幸的是,我正在运行 Windows 服务器。据我所知,Redis 和 Windows 的氛围不太好,但如果成功的话,那将是我的首选。对此唯一的另一个反对意见是,我试图让我的应用程序在运行外部应用程序方面尽可能简单。我正在运行 foreverhttp-proxy,因为它们都是基于 Node.js 的,因此在地球另一端并不是真正的系统管理员的白痴系统管理员不得不担心保持 0-1正在运行的程序,而不是 15 个。
    • 我想知道你是否可以在 cookie 解析器和会话使用声明之间安装一个自定义处理程序来处理你需要做的事情?我不知道这将如何工作,但这似乎值得探索。另一种选择是分叉 Express 会话代码并尝试在那里解决。伊克。
    • 是的,艾克是对的。自定义处理程序是我要求做的。我不是中间件专家。
    • 好的,如果有一个 Connect.SID cookie,但是那个特定的节点没有创建会话,应该怎么办?那个工人应该对请求做些什么吗?
    • 嗯,这正是正在发生的事情。理想场景 - 然后该工人“注册”cookie,并继续使用它,而不是发送新的 cookie。也许我可以查看 Connect 的源代码并找到存储会话的哈希值,然后在中间件处理 cookie 之前将其注入......
    【解决方案2】:

    我设法修改了 Connect 的源代码以使其正常工作,如下所示。但是,我仍在寻找将这些修改从 Connect 中移出的方法,因此我不必乱搞它的一个分支。

    node_modules\connect\lib\middleware\session.js - 在第 312 行之后追加:

    if (!sess) {
      store.sessions[req.sessionID] = JSON.stringify({
        "cookie": {
          "originalMaxAge": void 0,
          "expires": void 0,
          "httpOnly": void 0,
          "path": void 0,
          "passport": void 0,
        }
      });
      next();
      return;
    } 
    

    默认情况下,如果给定的 SID 不在其存储中,Connect 会创建一个新会话。这绕过了它,手动将其插入到商店中。

    如何将 Connect.js 中的这个移植到某个中间件,也许就在上面:

    app.use(express.cookieParser());
    app.use(express.session({ secret: "niceTry", cookie: { /* ... */ } }));
    

    更新

    好吧,我终于想通了:

    我在我的主 server.js 文件中添加了中间件,这可以在不修改 connect 源代码的情况下解决问题。

    var MemoryStore = require('connect/lib/middleware/session/memory');
    app.store = new MemoryStore();
    
    app.use(express.cookieParser());
    
    app.use(function(req, res, next){
    
      var cookie = req.signedCookies['connect.sid'];
      if (!cookie && req.cookies['connect.sid']) {
        cookie = connect.utils.parseSignedCookie(req.cookies['connect.sid'], app.cookieSecret);
      }
    
      app.store.get(cookie, function(err, sess){
        if (!sess) {
          app.store.sessions[cookie] = JSON.stringify({
            "cookie": {
              "originalMaxAge": void 0,
              "expires": void 0,
              "httpOnly": void 0,
              "path": void 0,
              "passport": void 0,
            }
          });
          next();
        } else {
          next();
        }
      });
    });
    
    app.use(express.session({ store: app.store, secret: app.cookieSecret, cookie: { httpOnly: false, maxAge: null } }));
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-02-01
      • 2019-12-21
      • 2019-03-04
      • 2011-08-13
      • 2013-09-28
      • 1970-01-01
      • 2020-05-02
      • 2014-10-14
      相关资源
      最近更新 更多