退出登录时如何使JWT令牌失效?

背景

JWT 最大的一个优势在于它是无状态的,自身包含了认证鉴权所需要的所有信息,服务器端无需对其存储,从而给服务器减少了存储开销。但是无状态引出的问题也是可想而知的,它无法作废未过期的JWT。

例如注销场景下,就传统的 cookie/session 认证机制,只需要把存在服务器端的 session 删掉就OK了。但是JWT呢,它是不存在服务器端的啊,好的那我删存在客户端的JWT行了吧?不行!被你在客户端删掉的JWT还是可以通过服务器端认证的。

使用JWT要非常明确的一点:JWT失效的唯一途径就是等待时间过期。
但是可以借助外力保存JWT的状态,常用的方案有两种,白名单和黑名单方式。

1. 白名单

在 Redis 维护有效的 JWT。登录成功时将生成的 JWT 存入 redis,并按照 jwt 中的过期时间来设置存入 Redis 的过期时间。登出时将该 JWT从 redis 中删除。

这样在 JWT 校验之前先查询白名单中是否有该 JWT,如果有则表明是有效的,然后进入 JWT 校验与解析的逻辑。有点像有状态的 session 的味道了。

2. 黑名单

在 Redis 维护无效的 JWT。登出(注销)时,将 JWT 放入redis中,并且设置过期时间为 JWT 的过期时间;请求资源时判断该JWT是否在redis中,如果存在则拒绝访问。
白名单和黑名单这两种方案都比较好实现,但是黑名单带给服务器的压力远远小于白名单,毕竟登出(注销)不是经常性操作。

3. 黑名单具体实现

究竟向 Redis 中存储什么?

如果直接存储JWT令牌可行吗?当然可行,不过JWT令牌可是很长的哦,这样对内存的要求也是挺高的。
熟悉JWT令牌的都知道,JWT令牌中有一个jti字段,这个字段可以说是JWT令牌的唯一ID了。因此可以将这个 jti 字段存入redis中,作为唯一令牌标识。

如何实现呢? 分为两步:

  • 网关层的全局过滤器从 JWT 中解析出 jti 和过期时间,根据 jti 从redis中查询是否存在黑名单中,如果存在则直接拦截,否则放行;
  • 注销接口中将JWT的 jti 字段作为key存放到 redis 中,且设置过期时间为 JWT 的过期时间。

--------over
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值