JWT 弊端解决思路(主动过期\权限更新)

JWT弊端解决思路(主动过期\权限更新)

了解JWT(JSON Web Token):
  • 优点
    • 服务器开销小,使用 Session + Cookie 需要服务器缓存用户数据,而使用 JWT 则是直接将用户数据下发给客户端,每次请求附带一并发送给服务器.
    • 扩展性好。服务器不缓存用户数据的好处是可以很方便的进行横向扩容
    • 更符合RESTFul API,遵循无状态原则,而JWT刚好把鉴权放在了客户端.
  • 缺点
    • 发下去的令牌服务器端无法控制,在退出或更改权限后,不会立即失效.令牌泄露后不安全
    • 增加带宽成本,使用JWT后,所有请求都需要携带Token,而token的体积很大,如果token过大,加解密过长,也会影响请求速度

(本篇就是围绕这两个缺点准备的解决思路)

安全问题:

JWT保存在客户端,由于JWT无状态去中心化的特点,首先要通过服务端保存一定的信息控制令牌随时失效保证安全,
(如果服务器端保存了令牌的状态,又和JWT的无状态化\去中心化相矛盾)

一、白名单

将所有发下去的令牌全都登记在白名单中

  • 缺点:数量比较大,记录了所有下发的token,而且又像session了
  • 优点:可以管理所有的令牌状态,还可以放入权限信息
  • 使用思路:白名单可以同时将用户的权限放入Redis中,在做令牌验证的时候再把用户的权限放进去
    (但是如果用户的权限发生变更,则之前的令牌中的权限信息就变的不准确)
二、黑名单

只将用户退出登录,或者手动失效的令牌记录下来

  • 缺点:无法管理用户申请的所有令牌,像修改密码后,无法使所有令牌失效,并且权限信息必须放在令牌内
  • 优点:退出登录这种的操作会很少,所以不会像白名单维护的数据量那么大
  • 解决办法:黑名单不能控制所有下发下去的令牌.当用户想要强制失效所有令牌,可以保存一个用户的信息和时间节点,黑名单验证比对中同时增加判断此用户该时间点前的令牌全部失效
三、较短的AccessToken

设置较短的AccessToken时间不做管理,记录所有refreshToken,即只保证refreshToken的安全

​ 比如将AccessToken的失效时间设置为3分钟,当AccessToken只剩下一分钟的有效期,就去调一遍刷新令牌的接口,拿着有效的refreshToken来获取新的AccessToken

  • 缺点:无法保证令牌实时失效,而且会大量的使用refreshToken获取新令牌.
  • 优点:这种AccessToken会更符合JWT令牌的初衷!

可以缩短AccessToken的有效时间到一个可接受的范围,如果只允许用户一个端登录,并且加上前端的配合(修改密码或权限后,自动获取新token,浏览器删除原token).也是一个比较合理的方案

(该方案就需要根据实际情况来权衡利弊)


JWT长度问题:

使用JWT时,如果要把用户的权限信息放入,则令牌会很长,加解密时间也会影响效率:

  • 在JWT中只存放一些少量的用户信息
  • 将权限信息放在网关中,当令牌到达时,使用令牌里的用户信息(或者权限标识)换取权限信息

(如果作为微服务之间的调用很多,或许可以将服务与服务之间的调用省去鉴权部分,直接调用,提高请求的处理时间)


用户权限信息的实时刷新问题:

如果将权限信息\或者权限标识信息放在JWT中,在用户权限发生改变时,下发的令牌权限并不会更新:

  1. 只能在权限改变时,失效所有令牌重新使用refreshToken获取新的令牌
  2. 或者将每个用户的权限信息保存在白名单中,修改权限就修改白名单

※配合强大的缓存服务:

为了实现权限即时更新,多端登录,修改密码,踢人下线等功能.我们永远躲不开有状态.服务端永远都得把控着所有的登录信息

  • 在大型的分布式系统中就要配合着强大的缓存实现:使用白名单,将所有登录系统的用户,全部放到缓存中,存入用户鉴权的所有信息.
  • 这样对缓存服务的要求会很高,也就是说:
    • 缓存服务的容量->系统可容纳的同时在线的用户数量
    • 缓存的查询速度->系统的访问速度

最后发现,我们使用JWT,大费周章的弥补了它无状态带来的问题,最后只是为了使用它的两个特点(优点):1.分布式2.可以存放少量的用户信息 …
其实这些工作使用cookie+分布式缓存也是可以实现的

然而我们不使用传统的session,就是因为在分布式系统的环境下,使用session还需要做多机器服务之间的数据共享和同步,显然不占优势,所以说才有了JWT或者分布式缓存这些东西

结语: 没有最好的解决方案,只有最适合的方案,一切都要根据实际需求来灵活运用

(仅个人理解,求指教)

你可能感兴趣的:(java,restful,服务器)