我先说一下我的理解: app.use(session({ secret: ‘keyboard cat’, })) 当设置secret后,express-session模块会在cookie中设置名为connect.sid的值,并且它的值是以“s:”开头的。这个值是cookieidd和secret加密后的结果。当重新访问相同页面时,express-session会提取出connect.sid的值并解析出对应的值进行解密。 我的疑问是解密之后的值应该与加密前的值进行对比,以判断cookie时候被改写。加密前的值是存储在哪里的,内存中吗? 以上是我的理解和疑问,如果有问题请大家指出,谢谢。 还有,为什么要对session id进行签名
跟楼主一样好奇,看了一下express-session里面对secret的用处:
所有的session-id都存储在cookie里面默认为connect.sid
。。
流程大概是
若本次cookie中没有connect.sid,则生成一个 [用secret生成connect.sid]
- 用uid-safe生成一个唯一id,记为sessionid,保证每次不重复;
- 把上面的connect.sid制作成
's:' + sessionid + '.' + sessionid.sha256(secret).base64()
的形式,实现在node-cookie-signature的sign函数; - 把sessionid用set-cookie返回给前端;
若本次cookie中包含connect.sid,则验证它是否是本服务器生成的 [用secret验证connect.sid]
- 取出cookie中的connect.sid,形式是上面的
's:' + sessionid + '.' + sessionid.sha256(secret).base64()
; - 从connect.sid中截取出sessionid=connect.sid.slice(2, connect.sid.indexOf(’.’));
- 用取出的sessionid再算一次 sessionid.sha256(secret).base64() 记为 mac;
- 截取connect.sid中’.'后的部分与mac对比;node-cookie-signature的unsign函数(用上次计算的sha256值和这次计算的sha256值进行比较,只要secret一样,结果就一样);
- 验证成功的sessionid继续往下走。
总结
用secret进行签名保证存在cookie中的connect.sid是本服务器上次生成的。除非知道secret,不然没办法伪造connect.sid中的sessionid,避免知道了sessionid生成算法的人(uid-safe)使用sessionid随便试探来攻击网站。 楼主的问题:解密后的值与加密前对比,及存储在哪里。 解密,算了两次带secret的sha256哈希值,判断两次sha256哈希值是否相等就达到效果了,哈希值没有解密的过程哦。存储,就是存储在connect.sid里面的 ‘.’ 后面的部分。
@albin3 非常感谢你,讲的很详细,搞懂了。
@albin3 非常浅显易懂!