前言
JWT 的原理是,服务器认证以后,生成一个 JSON 对象,发回给用户,就像下面这样。
{
"姓名": "张三",
"角色": "管理员",
"到期时间": "2018年7月1日0点0分"
}
以后,用户与服务端通信的时候,都要发回这个 JSON 对象。服务器完全只靠这个对象认定用户身份。为了防止用户篡改数据,服务器在生成这个对象的时候,会加上签名。
服务器就不保存任何 用户凭证数据了,也就是说,服务器变成无状态了,从而比较容易实现扩展。
然而,如果使用JWT实现,用户主动注销、强制登出(禁止登陆)、忘记密码、修改密码,JWT续签等方面的需求,就会让人头疼。
解决方案
根治
黑名单校验
凡是退出登录的token都放入黑名单中,定期清理。
每次用户请求服务器都校验token是否在黑名单
版本号校验
访问时从token中取出版本号和用户id 和 redis中存储 用户id和版本号 做对比,不一致则不给访问。
用户登出的时候在redis中把用户版本号加一。
过期时间校验
登录时token附带创建时间。访问时校验redis存储的过期时间,如果创建时间大于过期时间则不给访问。
Token副本校验
在redis中存储token副本,用户请求时候校验,如果redis中不存在该副本则不给通过。
无为而治
大体方案
分而治之
- 对于需要只有一个人一个终端登录的服务采用【版本号校验】解决方案
- 相当于乐观锁,但是用redis来实现,速度快
- 还方便踢人下线
- 相当于乐观锁,但是用redis来实现,速度快
- 对于需要注销token的服务,采用【Token副本校验 or 过期时间校验】解决方案
- 比查阅黑名单列表还要快得多
- 速度相当快
- 比查阅黑名单列表还要快得多
- 对于不需要注销token(大部分服务),则采用【无为而治】解决方案