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

Mer*_*erc 6 cookies node.js express

cookieParser()我们可以选择用一个秘密句子来签名cookie,这对于防止篡改非常有用.我知道cookie是用特殊值签名的,以防止篡改.

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

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

{ cookie: 
   { path: '/',
     _expires: null,
     originalMaxAge: null,
     httpOnly: true } }
Run Code Online (Sandbox Code Playgroud)

而不是:

{ testing: 'OOO' }
Run Code Online (Sandbox Code Playgroud)

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

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

芝加哥商业交易所.

rob*_*lep 12

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

这个问题是造成这一行cookieSession中间件(一些背景:options.secret是传递给关键cookieSession,req.secret是传递给钥匙cookieParser):如果你同时通过中间件的密钥,cookieSession假定它会发现在原始(未分析)的cookie req.cookies.

但是既然cookieParser已经获得了签名的cookie(并且之前正在运行cookieSession),它已经解析了cookie本身(因为签名密钥是相同的,它成功了),将其存储req.signedCookies 并从中删除req.cookies.所以就目前cookieSession而言,cookie没有设置.

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

app.use(express.cookieSession({
  cookie : { // <-- this object
    ...
  }
});
Run Code Online (Sandbox Code Playgroud)

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

FWIW:我不完全确定这是不是真的错误.它使用两个相同的签名机制的结果cookieParser,并cookieSession与由一个或另一个签订饼干之间没有区别.虽然可以通过始终检查cookie是否位于其中来修复req.signedCookies.

  • 真是太棒了,全面的答案.我知道这是一个非常小众的问题,但它值得+ 1s - 谢谢! (2认同)