同时使用 cookieParser() 和 cookieSession()?

Using cookieParser() and cookieSession() together?

提问人:Merc 提问时间:5/10/2013 更新时间:5/10/2013 访问量:4399

问:

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

默克。

节点 .js Cookie 表示

评论


答:

19赞 robertklep 5/10/2013 #1

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

这个问题是由中间件中的这一行引起的(一些上下文:是传递给的密钥,是传递给的密钥):如果你给两个中间件传递一个密钥,假设它会在 中找到原始的(未解析的)cookie。cookieSessionoptions.secretcookieSessionreq.secretcookieParsercookieSessionreq.cookies

但是由于它也拾取了签名的 cookie(并且它之前正在运行),它已经解析了 cookie 本身(并且因为签名密钥是相同的,它成功地这样做了),将其存储req.cookies 中并将其删除。因此,就而言,cookie 只是没有设置。cookieParsercookieSessionreq.signedCookiescookieSession

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

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

至于解决方案:要么为每个中间件使用不同的密钥,要么只将其中一个传递您的密钥,但不要同时传递两个密钥(前提是,如果您将其传递给 ,您的所有 cookie 都将被签名)。cookieParser

FWIW:我不完全确定这是否是一个真正的错误。这是对 和 使用相同签名机制的结果,其中 和 没有区别。尽管可以通过始终检查 cookie 是否位于 .cookieParsercookieSessionreq.signedCookies

评论

2赞 Merc 5/10/2013
多么美妙、全面的答案。我知道这是一个非常小众的问题,但它值得 +1 秒 - 谢谢!