7

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

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

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

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

而不是:

{ testing: 'OOO' }

(每次重新加载都会添加一个“o”)所以...

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

默克。

4

1 回答 1

15

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

问题是由中间件中的这一行cookieSession引起的(某些上下文:options.secret是传递给 的密钥cookieSessionreq.secret是传递给 的密钥cookieParser):如果您向两个中间件传递一个密钥,cookieSession则假定它将在req.cookies.

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

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

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

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

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

于 2013-05-10T05:29:11.950 回答