保存用户登录状态之Session和JWT
HTTP协议
我们知道HTTP协议是一种无状态的协议(服务器端不知道前后两次请求是否来自于同一个浏览器。所以,用户在第一次请求中登录后再在同一个浏览器中发第二次请求时,服务器并不知道这个用户已经登录了)。为了解决这个问题,就需要用一种机制来保存用户的登录状态/登录信息,常用的机制有Session和JWT.
Session
ASP.NET, ASP.NET MVC和ASP.NET MVC Core都支持用Session用保存用户的登录状态。Session的一种简单实现方式为:用户登录后会在服务器生成一个Session,每个Session里面包含SessionId(用来唯一标识一个Session)和对应的用户信息(如用户名,邮箱,电话等),所有的Session保存在内存的一块区域中。返回请求响应的时候,把SessionId包含到Cookie中,并把Cookie随着HTTP响应发给浏览器。用户下次发出请求的时候,会把包含了SessionId的Cookie发送给服务器,服务器根据Cookie里的SessionId,就知道这个用户已经登录了;根据SessionId和用户信息的对应关系,也可以拿到该用户的用户信息。
Session带来的两个问题:
问题1:在分布式集群架构中(例如当前流行的微服务架构),用户登录后就不能把Session保存到处理登录请求的那台服务器的内存里了,因为下次请求可能是由其它服务器来处理的。为了解决这个问题,可以增加一台Redis或者Memcached中心状态服务器,用来集中保存用户的登录状态。但这样做,相比从内存读取登录状态,性能会更低。
问题2:在分布式集群架构中,客户端可能是微信小程序,也可能是App,这样的客户端不支持或者不方便使用Cookie。
JWT
JWT是一段经过Base64编码后生成的字符串,人看不懂,要经过Base64解码才能看得懂,如下图所示:
登录到https://jwt.io,把JWT字符串拷贝进去,可以立即看到JWT各个部分的内容,也可以用代码来解码JWT的Header和Payload部分(解码前需要先验签以防止JWT被客户端篡改)。
JWT由Header(头部), Payload(负载), Signature(签名)三部分组成,如下图所示:
头部包含的是签名算法。
负载包含了用户名,过期时间等信息。你可以自己指定包含哪些信息。
签名里面是用签名算法生成的签名字符串。
用户成功登录后,服务器端会生成JWT并返回给客户端,客户端下次发送请求给服务器的时候会在请求头的Authorizaiton部分包含JWT(格式为Bearer JWT)。服务器收到请求后,会先把用户提交的JWT中的Header和Payload取出来,然后用服务器才知道的密钥按如下方式生成签名,并把生成的签名字符串和JWT中的签名字符串做比较,如果相等则认为用户已经登录,然后才会去拿Payload里面的用户信息。
HMACSHA256( base64UrlEncode(header) + "." + base64UrlEncode(payload), your-256-bit-secret )
由于JWT是保存在客户端,所以不会存在Session在分布式架构中出现的两个问题。
因为服务器每次都会检查签名,所以防止了JWT在客户端被篡改。
相关文章
- 【技术种草】cdn+轻量服务器+hugo=让博客“云原生”一下
- CLB运维&运营最佳实践 ---访问日志大洞察
- vnc方式登陆服务器
- 轻松学排序算法:眼睛直观感受几种常用排序算法
- 十二个经典的大数据项目
- 为什么使用 CDN 内容分发网络?
- 大数据——大数据默认端口号列表
- Weld 1.1.5.Final,JSR-299 的框架
- JavaFX 2012:彻底开源
- 提升as3程序性能的十大要点
- 通过凸面几何学进行独立于边际的在线多类学习
- 利用行动影响的规律性和部分已知的模型进行离线强化学习
- ModelLight:基于模型的交通信号控制的元强化学习
- 浅谈Visual Source Safe项目分支
- 基于先验知识的递归卡尔曼滤波的代理人联合状态和输入估计
- 结合网络结构和非线性恢复来提高声誉评估的性能
- 最佳实践丨云开发CloudBase多环境管理实践
- TimeVAE:用于生成多变量时间序列的变异自动编码器
- 具有线性阈值激活的神经网络:结构和算法
- 内网渗透之横向移动 -- 从域外向域内进行密码喷洒攻击