这节课开始带大家设计实现一个套支持多平台登录,Token泄露检测、同平台多设备登录互踢功能的用户认证体系,这套用户认证体系既可以在你未来开发产品时直接应用,也可以在其基础上根据需要扩展出其他功能.它会作为我们后面商城App后端服务的的用户认证体系,同时又足够独立,能拿到自己的项目中去快速把用户认证给搭建起来。
说到Token,很多人一开始想到的可能是JWT -- JSON Web Token。
JWT因为其本质是存储在客户端cookie中,发布出去后服务端无法对其进行主动过期等控制,所以应用场景跟这里介绍的用户认证体系不一样,我们今天介绍的这套用户认证体系,在用户体验、安全性和稳定性上都会更完善,更适合在拥有C端用户的产品上或者是拥有多个产品线的公司级项目中应用。
想要设计出一个能满足企业级项目需求的用户认证体系,我们需要从用户体验、安全和稳定性上来考虑,同时也要收集产品经理、前端开发对其在功能性上的要求,不能为了只考虑稳定、高效而忽略了用户体验。
从功能的用户体验、安全性和稳定性来看,通常一个足够支撑企业级项目的认证系统要满足一下要求:
- 用户体验:
a.保证用户登录后,在较长时间内不需要重新登录,比如15天或者30天内登录过就不需要让用户再主动登录。
b.支持多平台登录,用户在App平台上的登录行为不会踢掉用户在H5端的登录状态。
c.在同一平台上,如果发生多设备登录要能把老设备的登录态踢掉。
- 安全性:
- 用户认证用的Token不可伪造,除发放Token的服务端外无法自行生成Token。
- Token 具有较快的过期机制(1~2 h),减少被人获取Token后伪装成用户进行操作的几率。
- 能有发现机制,发现Token被窃取,或者客户端存在旧Token未更新;
- 稳定性:
- Token 具有自解释性,即自带某些信息,在某些极端恶劣情况下,依然能提供最基本的服务。
用户认证体系的实现思路和方案
为什么所有商用项目都需要用户认证体系呢?最简单的一个原因是:因为用户的ID不能外漏。在产品内部与用户相关的数据资产都是使用用户ID标记用户归属的,一旦外漏造成的风险和损失不可预估。
在我们设计的认证体系中,用户登录后返回给前端以下Token信息。
为什么有两个Token
主要考虑下面三个因素:
- 一个Token即负责认证又负责刷新,这种方式前端页面会有并发请求的情况,Token 的刷新需要加锁,会带来很大的开销;
- 无法保证前端刷新 Token 的互斥时,会出现Token反复失效的情况;
- 还有就是我们设计的refreshToken能帮助我们发现Token被盗和过期未更新的问题
Token信息的构成和存储
服务端 Token 存储的信息(服务端记录的信息)如下:
用户登录授权,在给用户发放Token的同时服务端会存储三份信息,用于会话管理和认证。
图片
它们存储的主要信息和其存储方式如下:
图片
上面我们一直提到了用户登录平台Platform、SessionId ,它们分别是什么呢?
- Platform:是我们自己定义的用户登录平台,比如H5、App、Web 之类的,用户登录时需要在Header头中携带约定的Platform值,用于标记用户的不同登录端。这个字段的设置是为了保证不同端的登录和Token刷新相互之间不会受到影响,避免在App上刷新Token,导致H5 的用户Token失效的问题。
- SessionId:会话ID,登录后的唯一标识,Token刷新时不会改变会话ID,仍然设置为原SessionId,只有在用户重新登录后SessionId才会改变,项目可以使用它记录一些与登录行为关联的数据。
Token验证和刷新的流程
Token的验证和刷新流程给大家准备了详尽的UML活动图和案例进行讲解
图片