基于 token 在鉴权,体现在 token 的生成方式以及存储方式上的差异,在实现上有多种方式。最常见都有以下两种:
一)弱约定型
- 特点
- token 的生成根据需求和喜好自定义,常见是(用户信息+时间戳)的base64/md5编码。
- 需要借助其他缓存中间件(如redis)保存 token 和用户信息
- 客户端发送发送请求到服务器进行鉴权时,除了必须带上 token 外,必须带上用户唯一id。服务端检验类似于 username + password 校验机制
- 鉴权通过后,从缓存中返回该用户的用户信息给客户端
- 服务器无需存储秘钥
- 说明
- 因为 token 中加入了时间戳,因此一般无法从 token 中直接逆向获取用户信息,必须另外存储用户信息,供鉴权通过后返回客户端
- 缺点
- 需要额外使用第三方中间件,增加使用成本与不确定性(中间件持久层出现问题)
二)强约定型
- 特点
- token 的生成根据业内规定,按照一定规则生成
- token 保存的用户信息,可以逆向解析,供鉴权通过后返回客户端直接使用
- 不用单独存储用户信息
- 服务器需要存储秘钥
- 服务端检验类似于 业内规则 + 秘钥
- 无需额外借助其他缓存中间件
- 说明
- 因为是业内达成的规则,因此 token 中保存的用户信息是可逆向解析得到的。无需另外存储用户信息,因此无需第三方组件(redis等)
- 缺点
- JWT的最大缺点是服务器不保存会话状态,所以在使用期间不可能取消令牌或更改令牌的权限。也就是说,一旦JWT签发,在有效期内将会一直有效。从而无法实现多客户端使用相同账号登录时,只保持一端在线的需求
- 经典实现:JWT
- jwt信息包括,header + playload + secret
- 用户信息存放在playload 里
- token 组成:base64Url(header).base64Url(playload).SHA256(base64Url(header).base64Url(playload), '秘钥')
- 因此规矩上面 token 的组成,可以很容易得到playload中的用户信息
- 因为无法知道秘钥,因此无法修改playload中任何的用户信息
- header 包含类型与加密算法的声明两部分,playload 包含标准中注册的声明,公共的声明以及私有的声明三部分;
- 关于更加详尽的header 和 playload 中包含的各部分更详尽的说明,可自行查资料了解
- 流程图如下