JWT 存在的问题
在 JWT 中我们介绍了JWT,且在文章中提到了 JWT 的特点:JWT 一旦签发便无法撤销,在过期之前无论是谁携带该token进行相关数据的访问以及操作,都能够被认证通过。
JWT 签发的形式类似与微信开放平台对接时接口调用凭证的获取,该凭证一旦获取便默认你拥有了相关的访问操作权限,且默认你有保证该凭证不会泄露的能力。针对开放平台对外开发接口的身份认证,JWT可以说是量身定做。
但是实际应用场景中,出于业务上的问题,或者由于签发 token 泄露需要对已经签发的token进行主动废弃处理,减少用户损失(小公司用户就是上帝)。
针对这类应用场景,JWT 的不足之处显而易见。
思考:如何解决?
1、如何对JWT已签发的token 进行废弃处理?
如果想要对已签发的token进行废弃处理,就需要将token存入如redis、磁盘等存储介质中,只有进行了数据存储,才能够针对数据进行操作。
2、如果将JWT 签发的token存入存储介质中,那和 传统 session 认证又有什么区别?
第一、单单从分布式系统来谈,在生产环境一般会存在如 redis 集群之类的缓存机制,而单从存储 JWT 来说,无需多做任何架构上的变更,只需在相关缓存介质中开辟相应的空间进行JWT数据存储即可。
第二、无需存储并维护所有 JWT 签发的 token ,只需要针对指定需要进行废弃 JWT 签发 token 操作的用户进行特殊存储。这样相比较于 session 对每个用户都进行存储来说,该方式存储的数据量以及占用的内存空间大小都远小于 session 维护的数据量。
3、如何进行存储?
一、签发的token,对应的payload 中增加存储信息:createTime - 签发时间。
二、在缓存,如 redis 缓存中存储如下数据:用户唯一表示 - 黑名单时间
设计与实现
设计
redis 存储数据过期时间为 token过期时间
这样一来可以保证在该设定时间前的 token 都被认定为失效,并且在一定时间内,所有 token 已经真实过期之后,redis 中数据能够及时从redis 中被清除。在拦截器中,进行校验
实现
JWT 工具类部分代码
JWT 签发 token ;
其中 createTime 用来做废弃判定
JWT 获取 createTime
jwt 服务 规范定义 IJWTService

JWT 服务具体实现 JWTServiceImpl
进行 token 废弃操作:就是存入一个键值对,用户唯一标示:当前时间时间戳
检查某一用户是否存在限制记录,如果存在比对该 token 签发时间是否已过期,过期则为被限制token,反之不受限
检查token有效性,包括是否被限制等
工作流程
用户登录,JWT 签发 token,并在 token 中的payload 中添加了 createTime -签发时间
主动废弃的 token,如退出登录需要废弃,在缓存 redis 中存入废弃记录。
用户访问接口时,在API 网关中(或者Interceptor拦截器中)进行拦截并进行权限判定。其中包括检查 token的有效性(是否自动过期,是否无效,是否被强制过期)
该方式的可行性
从存储空间占用上来说,相比较于原始 JWT 签发 token,需要占据一定量的内存空间。但是对比传统 seesion 的身份认证,数据结构较小,占用的内存空间也相对小。
可能会存在由于每个用户都进行退出登录操作,导致针对于每个用户都需要维护一条数据。但是从整体上来说,该事情发生的概率较小,即使发生了,其维护的记录数也于传统 seesion 管理存放的数据数持平,并且由于我们存储的只有一个时间戳,相比较seesion 直接存放一长串数据来说,数据结构体积相对小,占用的空间也会较小。

长按二维码关注,一起共同成长!





