Node.js / Connect使用现有的Connect.SID

时间:2013-11-25 07:19:56

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

我有鸡和蛋的问题。

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

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

问题

显然,如果请求的Connect.SID未向 Node 注册,则Connect会分配新ID

所以,我有一个新的Connect.SID。我的HTTP代理记录ID 12345并将其路由到工作人员#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,它会跳过它?

2 个答案:

答案 0 :(得分:5)

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

答案 1 :(得分: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 } }));