一起使用cookieParser()和cookieSession()?

时间:2013-05-10 04:41:13

标签: node.js cookies express

cookieParser()为我们提供了使用秘密句子签名cookie的选项,这对于防止篡改非常有用。我知道cookie是用特殊值签名的,以防止篡改。

我刚刚发现了cookieSession(),我发现它是服务器存储的cookie的伟大的替代品(我只存储{ loggedIn = true, userId=763487246824632},它永远不会增长)。

但是......我发现为cookieParser()设置“秘密”会破坏事情,如果秘密句子匹配,cookieSession()将停止工作。 原因似乎是如果cookie使用相同的秘密进行签名,那么cookieParser()实际上会接受并解析它。奇怪的是,一旦cookieParser()完成了它的工作,而使用相同的签名秘密,会话就被设置为:

{ cookie: 
   { path: '/',
     _expires: null,
     originalMaxAge: null,
     httpOnly: true } }

而不是:

{ testing: 'OOO' }

(每次重新加载'o') 所以......

  • 我的分析是否正确?
  • 如果秘密句子匹配,你知道为什么会话设置为那个奇怪的{ cookie对象吗?

Merc的。

1 个答案:

答案 0 :(得分:12)

您的分析是正确的,我可以重现它。

问题是由cookieSession中间件中的this line引起的(某些上下文:options.secret是传递给cookieSession的密钥,req.secret是传递的密钥至cookieParser):如果您将两个中间件都传递给密钥,cookieSession会假定它会在req.cookies中找到原始(未解析)Cookie。

但是由于cookieParser已经获取了签名的cookie(并且它在cookieSession之前运行),它已经解析了cookie本身(并且因为签名密钥是相同的,所以它成功了这样做),将其存储在req.signedCookies 中,并将其从req.cookies 中删除。因此,就cookieSession而言,cookie并未设置。

您看到的对象是默认会话内容(cookie配置中的cookieSession属性):

app.use(express.cookieSession({
  cookie : { // <-- this object
    ...
  }
});

至于解决方案:要么为每个中间件使用不同的密钥,要么只传递其中一个密钥,但不能同时传递两者(理解如果将其传递给cookieParser全部您的Cookie将被签名)。

FWIW:我不完全确定这是不是真的错误。这是对cookieParsercookieSession使用相同签名机制的结果,不区分由一个或另一个签名的cookie。虽然可以通过始终检查cookie是否位于req.signedCookies

来解决