什么是会话管理
本文最后更新于:8 个月前
什么是会话管理?会话管理的3种方式,针对https协议的会话管理又是什么?
什么是会话管理
会话管理基于一个背景,即http是无状态的,在一次请求结束后,下一次请求服务端不知道请求是由哪个用户发送过来的。
采用各种方法,让服务器记住用户的身份,就是会话管理。一共有3种方法
- 基于server端的 session
- cookie-based
- token-based
一、服务端session管理
早期web应用采用的方式,目前仍在大量使用的方式,适合单体服务网站使用
工作原理
用户第一次发送请求,服务端创建一个对象保存这次会话的数据,同时分配一个sessionId给这次请求,通过cookie返回给客户端
注意:
- session对象里面写入客户端的信息,例如用户登陆后写入登陆凭证、用户退出后删除用户信息,以此实现用户关联
- session有一个有效时间,过期自动销毁。只要有效期内再次访问,有效期就被延长
客户端再次请求服务端时,会自动携带上cookie,服务端便能从cookie中获取到sessionId,以此来管理会话
客户端发起登陆请求,服务端验证通过后,再sessionId对应的session里放入登陆凭证。以后碰到需要登陆权限的访问时,查看对应的session里有无登陆凭证。
缺点
- 占用服务端储存
- 如果服务端有多台服务器,需要再所有服务器之间拷贝同一份session信息
- 如果多个应用想共享session,需要解决跨域问题
前两个问题现在已经有比较成熟的解决方案了,那就是可以使用 Redis 这种中间服务来托管 session 的增删改查。
对于第三个问题,解决起来就比较麻烦了,前后端都需要做处理,因为它最关键部分是 cookie,所以只要保证多个应用之间的 cookie 能互通跨域就 OK
二、cookie-based
第一种方式是把登陆凭证放到了服务端上,因此造成了前2个缺点。于是当前方式将登陆凭证改为放置在客户端
工作原理
用户发起登录请求,登录信息验证通过后,把用户信息处理成一个登录凭证,这个凭证需要有创建时间和过期时间,便于服务端处理过期。
服务端再对登陆凭证进行签名、加密等操作,然后写入cookie,返回给客户端
客户端再次发送请求时,服务端从请求头的cookie中获取登陆凭证,然后进行解密验证,获取用户身份
缺点
- 依然存在需要解决跨域的问题
- cookie大小限制(4kb),存不了太多数据
三、token-based
与cookie-based类似,只不过前者用cookie保存信息,后者用token保存信息。本质上都是将登陆凭证放到客户端
工作原理
- 户发起登录请求,登录信息验证通过后,服务端生成一个token,返回给客户端
- 客户端再发送请求时,携带上这个token
注意:客户端和服务端需要先约定好 token 交换的方式
优势
解决了占用服务端资源、服务器之间共享麻烦、需要跨域的问题
弊端
安全性不如前两者高,容易被伪造,最关键是签名部分,如果签名被破译,就不安全了。
四、针对https协议的会话管理
为了优化https的性能,减少TLS握手的次数,于是采用「会话复用」的方式。这里就涉及到了缓存「对称加密密钥」的问题,而这个问题也可以视为「会话管理」。
为了实现「针对https协议的会话管理」,可以采取上述的前两种方式:
- Session ID
- Session Ticket
Session ID的方式
第一种Session ID的工作原理是,客户端和服务器首次 TLS 握手连接后,双方会在内存缓存会话密钥,并用唯一的 Session ID 来标识,Session ID 和会话密钥相当于 key-value 的关系。
当客户端再次连接时,hello 消息里会带上 Session ID,服务器收到后就会从内存找,如果找到就直接用该会话密钥恢复会话状态,跳过其余的过程,只用一个消息往返就可以建立安全通信。当然为了安全性,内存中的会话密钥会定期失效。
缺点在上面第1点中已经提到过了
Session Ticket的方式
客户端与服务器首次建立连接时,服务器会加密「会话密钥」作为 Ticket 发给客户端,交给客户端缓存该 Ticket。
客户端再次连接服务器时,客户端会发送 Ticket,服务器解密后就可以获取上一次的会话密钥,然后验证有效期,如果没问题,就可以恢复会话了,开始加密通信。
这些会话重用技术虽然好用,但是存在一定的安全风险,它们不仅不具备前向安全,而且有重放攻击的风险,所以应当对会话密钥设定一个合理的过期时间。