Egg05 Session
Session是Web应用在Cookie基础上的封装,主要目的就是进行用户身份识别。
关于Session
为什么要有Session
HTTP是无状态的协议,但是在很多情况下服务端需要记录用户的状态,典型的场景比如用户登录、购物车等。所以服务端需要某种机制来识别具体的用户,这种机制就是Session。
当用户购物时,服务端并不知道是那个用户操作的,所以需要为特定的用户创建特定的Session,来标识、跟踪这个用户,才能弄清楚用户购物车内的东西并且不与其他用户的购物车混淆。
Session的保存
Session是保存在服务端的,有一个唯一的标识。服务端保存Session的方法很多,内存、数据库、文件都有。大型的网站一般会有专门的Session服务器集群,用来保存用户回话,这个时候Session是保存在内存的。
Session如何是识别用户身份
Session是使用Cookie来识别用户身份的。每次HTTP请求时,客户端会发送响应的Cookie到服务器。
第一次创建Session的时候,服务端会在HTTP响应中告诉客户端,需要在Cookie里面记录一个Session ID,以后每次请求都需要把这个ID发送到服务器,服务端就知道是哪个用户发送的请求了。
这个Session ID是维持Session回话的客户端的唯一标识,是Session实现的核心。
如果浏览器禁用了Cookie,Session ID需要通过url来传递。
与cookie的区别
Session是存储在服务端的数据,用来跟踪是被用户的状态,可以保存在集群、数据库、内存、文件中
Cookie是客户端保存信息的一种机制,用来记录用户的一些信息,会随着网络请求发送给服务端,也是实现Session的一种方式
其他的实现方式
除了使用Session实现用户身份的识别,也可以使用JWT的机制实现,详情可以参考之前的笔记《JS42 JWT实现单点登录》
Egg中对Session的处理
Egg内置了egg-session插件,可以直接使用ctx.session
访问或者修改当前用户的Session
1 | class HomeController extends Controller { |
Session可以直接读取或者修改,删除的话直接置为null
就可以了:
1 | ctx.session = null; |
需要特别注意的是,设置Session属性时要避免以_
开头,并且不能为isNew
这个属性,会造成字段丢失。
Session的实现是基于Cookie的,默认配置下,用户Session的内容加密后直接存储在Cookie的一个字段中:
用户每次发送请求时都会带上这个Cookie,在服务端解密后使用。
Session的默认配置如下:
1 | exports.session = { |
这些参数中,key
代表存储Session的Cookie的键值对的key
是什么,其他的参数都与Cookie的设置参数相同。在默认的配置下,存放Session的Cookie将会加密存储、不能被前端JavaScript访问,这样保证用户的Session是安全的。
扩展存储
Session默认放在cookie中,当Session过大时,会带来两个问题:
- cookie存储空间有限制,可能无法存储过大的Session
- 每次请求都要发送庞大的Cookie信息
Egg提供了将Session存储到除了Cookie之外的其他存储的扩展方案,只需要设置app.seesionStore
就可以将Session存储到指定的位置
1 | // app.js |
可以使用egg-session-redis配合egg-redis,将Session存储到redis中。
注意,一旦选择了将Session存储到外部存储中,就意味着系统强依赖于这个外部存储,当它挂了后,我们就完全无法使用Session的相关功能了。因此Egg推荐大家只将必要的信息存储到Session中,保持Session的精简并使用默认的Cookie存储。用户级别的缓存不要存到Session中。
Session实践
修改用户Session失效时间
Session的配置中的maxAge
只能设置全局Session的有效期,有一些登陆页面的“记住我”的功能会让登陆用户的Session有效期更长,这种针对特定用户的Session有效时间社会可以通过ctx.session.max
来实现
1 | const ms = require('ms'); |
延长用户Session有效期
默认情况下,当用户请求没有导致Session被修改时,框架不会延长Session的有效期。有些时候希望用户长时间都在访问我们的站点,要延长其Session有效期,不让用户退出登录状态。
框架提供了renew
配置项来实现上述功能,它会在发现当用户Session的有效期仅剩下最大有效期的一般时,重置Session的有效期。
1 | // config/config.default.js |