day 78
RBAC
- 基于角色的访问控制 Role-based Access Control
JWT
- Json Web Token
优点
- 数据库不需要存储token, 所以服务器的IO操作会减少
- 客户端存token, 服务器只存储签发校验算法, 执行效率高
- 签发与校验算法在多个服务器上可以直接统一, 所以在JWT认证规则下, 服务器做集群非常便捷
实现原理
- token由三部分组成: 头, 载荷, 签名
- 每一部分数据都是一个json字典, 头和载荷采用 base64 可逆加密算法加密(可反解), 签名采用 HS256 不可逆加密(不能反解)
- token中必须包含过期时间以保证安全性和时效性
三大组成的内容
- 头(基本信息): 可逆不可逆采用的加密算法, 公司名称, 项目组信息, 开发者信息, ...
- 载荷(核心信息): 用户主键, 用户账号, 客户端设备信息, 过期时间, ...
- 签名(安全信息): 头的加密结果, 载荷的加密结果, 服务器的安全码(盐), ...
签发算法
-
头内容写死, 基本信息都是不变的
==> 将数据字典转为json字符串, 再将json字符串加密成base64字符串
-
载荷内容, 如用户账号, 客户端设备信息等由客户端提供, 用户主键是校验过账号密码之后才能确定的, 过期时间是通过当前时间与配置的有效期来获取
==> 将数据字典转为json字符串, 再将json字符串加密成base64字符串
-
签名内容, 先将头的加密结果, 载荷的加密结果作为成员, 再从服务端拿安全码
==> 将数据字典转为json字符串, 再将json字符串加密成HS256字符串
-
将三个字符串用 "." 连接产生三段式token
校验算法
- 从客户端提交的请求中拿到token, 用 "." 分割成三段
- 第一段(头)可以不用解密
- 第二段(载荷), 先用base64解密成json字符串, 再转成json字典数据
- 用户主键与用户账号 => 查询User表确定用户是否存在
- 设备信息 => 和本次设备信息进行比对, 判断是否是同一设备
- 过期时间 => 和当前时间比对, 判断该token是否在有效期内
- 第三段(签名), 采用加密碰撞校验,
- 同样将头, 载荷加密字符串和数据库安全码形成json字典, 转换成json字符串
- 采用不可逆HS256加密形成加密字符串
- 新的加密字符串与第三段签名碰撞对比, 如果两者一致才能确保token是合法的
- 以上校验通过后, 得到的user对象, 就是该token代表的登录用户(django项目一般把登录用户对象存放在request.user中)
刷新算法
- 要在签发的token的载荷中, 额外添加两个时间信息: 第一次签发token的时间, 最多往后刷新的有效时间
- 每次请求携带token, 不仅要验证token是否合法, 还要额外请求刷新token的接口, 完成token的刷新(先验证token是否过期)
- 服务端不仅要配置过期时间, 还需要配置最长刷新时间