前段时间遇到一个很奇怪的问题,一个给公司运营提供的后台服务,登录是用express-session实现的简易身份验证,使用时每次重新登录第一次输入验证码总会出错,由于是公司内部的后台服务,所以一直没看,今天研究了一下,发现是一个并发请求导致的session状态被重写问题。
使用express-session
首先要了解的是express-session这一中间件,当浏览器访问服务器并发送第一次请求时,服务器端会创建一个session对象,生成一个类似于key(connect sid),value(session)的键值对, 然后将key(connect sid)返回到浏览器(客户)端作为cookie保存,浏览器下次再访问时,携带key(connect sid),找到对应的value(session) 。 客户的信息都保存在session中。 session 的解析依赖 cookieParser,先是从 cookie 中读取加密的 connect sid,再通过 cookieParser 解析成一个对应的 session id,该 session id 保存在 req.sessionID 中(因此 cookieParser中间件应该放到 session 之前)。
epxress.session 用的是 connect 的 session 中间件,而 session 中间件在起作用的时候,先是通过 session 的 Store 对象来读取当前的 session 数据,所以当多个请求并发过来的时候,他们拿到的会是同一份 session 数据。每个协议调用在 res.end() 的时候这个阶段 session 的数据会被自动 save 一次(req.session.save() 可以主动保存)。其内部的代码类似这样的: