实战!退出登录时如何借助外力使JWT令牌失效?(一)

love374
发布于 2022-7-11 11:47
浏览
0收藏

 

大家好,我是不才陈某~

 

这是《Spring Cloud 进阶》第17篇文章,往期文章如下:

  • 五十五张图告诉你微服务的灵魂摆渡者Nacos究竟有多强?
  • openFeign夺命连环9问,这谁受得了?
  • 阿里面试这样问:Nacos、Apollo、Config配置中心如何选型?这10个维度告诉你!
  • 阿里面试败北:5种微服务注册中心如何选型?这几个维度告诉你!
  • 阿里限流神器Sentinel夺命连环 17 问?
  • 对比7种分布式事务方案,还是偏爱阿里开源的Seata,真香!(原理+实战)
  • Spring Cloud Gateway夺命连环10问?
  • Spring Cloud Gateway 整合阿里 Sentinel网关限流实战!
  • 分布式链路追踪之Spring Cloud Sleuth夺命连环9问?
  • 链路追踪自从用了SkyWalking,睡的真香!
  • 3本书了,7万+字,10篇文章,《Spring Cloud 进阶》基础版 PDF
  • 妹子始终没搞懂OAuth2.0,今天整合Spring Cloud Security 一次说明白!
  • OAuth2.0实战!使用JWT令牌认证!
  • OAuth2.0实战!玩转认证、资源服务异常自定义这些骚操作!
  • 实战干货!Spring Cloud Gateway 整合 OAuth2.0 实现分布式统一认证授权!
  • 字节面试这样问:跨库多表存在大量数据依赖问题有哪些解决方案?


今天这篇文章介绍一下如何在修改密码、修改权限、注销等场景下使JWT失效。

 

文章的目录如下:

 实战!退出登录时如何借助外力使JWT令牌失效?(一)-鸿蒙开发者社区
解决方案
JWT最大的一个优势在于它是无状态的,自身包含了认证鉴权所需要的所有信息,服务器端无需对其存储,从而给服务器减少了存储开销。

 

但是无状态引出的问题也是可想而知的,它无法作废未过期的JWT。举例说明注销场景下,就传统的cookie/session认证机制,只需要把存在服务器端的session删掉就OK了。

 

但是JWT呢,它是不存在服务器端的啊,好的那我删存在客户端的JWT行了吧。额,社会本就复杂别再欺骗自己了好么,被你在客户端删掉的JWT还是可以通过服务器端认证的。

 

使用JWT要非常明确的一点:JWT失效的唯一途径就是等待时间过期。

 

但是可以借助外力保存JWT的状态,这时就有人问了:你这不是打脸吗?用JWT就因为它的无状态性,这时候又要保存它的状态?

 

其实不然,这不被逼上梁山了吗?不使用外力保存JWT的状态,你说如何实现注销失效?

 

常用的方案有两种,白名单和黑名单方式。

 

1、白名单
白名单的逻辑很简单:认证通过时,将JWT存入redis中,注销时,将JWT从redis中移出。这种方式和cookie/session的方式大同小异。

 

2、黑名单
黑名单的逻辑也非常简单:注销时,将JWT放入redis中,并且设置过期时间为JWT的过期时间;请求资源时判断该JWT是否在redis中,如果存在则拒绝访问。

 

白名单和黑名单这两种方案都比较好实现,但是黑名单带给服务器的压力远远小于白名单,毕竟注销不是经常性操作。

 

黑名单方式实现
下面以黑名单的方式介绍一下如何在网关层面实现JWT的注销失效。

 

究竟向Redis中存储什么?

 

如果直接存储JWT令牌可行吗?当然可行,不过JWT令牌可是很长的哦,这样对内存的要求也是挺高的。

熟悉JWT令牌的都知道,JWT令牌中有一个jti字段,这个字段可以说是JWT令牌的唯一ID了,如下:

 实战!退出登录时如何借助外力使JWT令牌失效?(一)-鸿蒙开发者社区
因此可以将这个jti字段存入redis中,作为唯一令牌标识,这样一来是不是节省了很多的内存?

 

如何实现呢? 分为两步:

  1. 网关层的全局过滤器中需要判断黑名单是否存在当前JWT
  2. 注销接口中将JWT的jti字段作为key存放到redis中,且设置了JWT的过期时间


1、网关层解析JWT的jti、过期时间放入请求头中
在网关的全局过滤器GlobalAuthenticationFilter中直接从令牌中解析出jti和过期时间。

 

这里的逻辑分为如下步骤:

  1. 解析JWT令牌的jti和过期时间
  2. 根据jti从redis中查询是否存在黑名单中,如果存在则直接拦截,否则放行
  3. 将解析的jti和过期时间封装到JSON中,传递给下游微服务


关键代码如下:

 实战!退出登录时如何借助外力使JWT令牌失效?(一)-鸿蒙开发者社区
2、下游微服务的过滤器修改
还记得上篇文章:实战干货!Spring Cloud Gateway 整合 OAuth2.0 实现分布式统一认证授权!中微服务的过滤器AuthenticationFilter吗?

 

AuthenticationFilter这个过滤器用来解密网关层传递的JSON数据,并将其封装到Request中,这样在业务方法中便可以随时获取到想要的用户信息。

 

文章转自公众号:码猿技术专栏

标签
已于2022-7-11 11:47:35修改
收藏
回复
举报
回复
    相关推荐