express 的session不同步(被重写)

问题是这样的,在登录时要进行验证码认证,进入登录页后马上请求验证码,同时server端要将生成的验证码存放在对应的session里面。但是发现验证码并没有被正确的写到session里面。
代码类似是这样

getCaptcha(req, res) {
    console.log(req.session.captcha, 'old captcha')
    const captcha = Math.random().toString(10).substr(2, 4)
    req.session.captcha     = captcha
    console.log(req.session.captcha, 'new captcha')
    const captchaImage = image(captcha) // 伪代码:生成验证码的base64的图片
    res.set('Content-Type', 'image/png')
    res.end(img)
}

多次刷新后表现结果是:
2367 old captcha
4567 new captcha
2367 old captcha
7809 new captcha
2367 old captcha
5690 new captcha
也就是session没有被更新,或者说被某些方法重新给写回去了。

阅读 4.5k
3 个回答

NodeJS 建议用来做无状态服务器!。假设你如此开发,部署必然是有负载均衡或者pm2多核。用户A在1核上登录,第二次请求极可能会发送到2核状态立马就丢失了。使用 session 建议使用其他方案替代。

看看你express session怎么配的,贴关键代码

查找原因,原来,并发操作时,多个请求取到的是相同的session,在getCaptcha方法更改了session后,另外两个请求在 res.end() 的时候这个阶段 session 的数据会被自动 save 一次(req.session.save() 可以主动保存)。
也就是说在获取验证码的协议(该协议在 session 中特别保存了一次验证码的数据),之后其他请求其他资源协议中附带的 session在 res.end() 的时候重复保存然后把开始的验证码数据给覆盖掉了。
看起来就好像是一个不同步的问题一样,其实就是并发的时候数据重复写入了。
详细解释可以参考: https://cnodejs.org/topic/536...