需求:

JWT泄露、密码重置等场景下,需要将未过期但是已经不安全的JWT主动失效。

本文不再复述JWT的基础知识,不了解的小伙伴可以自行Google一下。这里主要是针对以上需求聊一聊解决方案。如果服务端发给客户端的JWT还在有效期内,但是变得不安全,服务端需要及时将这些JWT标识出来并作废掉。相较于session机制,服务端对JWT的控制要弱很多。JWT一旦签发,就脱离了服务端的掌控。通常情况下,服务端只能通过设置JWT的过期时间“exp”声明,使得JWT在过期后被动失效。

正所谓鱼与熊掌不可兼得。在我们享受JWT便利性的同时,也要设计复杂点的机制来弥补服务器对JWT控制能力弱的缺点。网上有人建议服务器将签发的JWT都存一份到分布式缓存中,这样JWT就能被跟踪和标识。这种方式虽然解决了问题,但是每个JWT都保存起来,每次校验都做查询的方式同分布式session几乎无分别。这相当于放弃了JWT占用服务器空间小、有效性校验速度快的优点。在没有跨域资源访问的需求场景下,分布式session的方案反而更有优势,至少可以在session中保存敏感信息,而不用担心在客户端被泄露。

下面讲一下我在当前项目中使用的JWT控制方案:

  1. 每个JWT必须设置过期时间,并且该时间不要设置的过长。

  2. 在用户登陆表中,为每个用户分配一个“token_group_id”字段。该字段保存一个随机字符串。

    

  3. 在JWT的payload中增加“groupId”声明。签发JWT的时候,将用户对应的“token_group_id”字符串写入该声明。

    {

      "exp": 1525256018000,

      "groupId": "jeJ4IVpR17z68Q0cTr53gQ25e588P653"

    }

  4. 在服务端的分布式缓存上保存一个“groupId”黑名单列表。如果用户的JWT泄露或者重置密码等需要作废已经签发给用户的JWT时,为该用户生成一个新的“token_group_id”存入用户登陆表。将原有的“token_group_id”加入黑名单。

  5. “token_group_id”在黑名单中的保存时间是JWT的过期时间。过期后“token_group_id”自动从黑名单中删除。

  6. 所有需要做JWT有效性校验的服务器启动时访问分布式缓存将黑名单下载到本地内存。并且订阅分布式缓存的消息推送功能,在黑名单发生增删的时候,接收推送消息同步修改内存中的黑名单列表。

  7. 服务器做JWT校验的时候,除了校验过期时间,还要查询内存中的黑名单列表。若JWT的“groupId”在黑名单中,则判定该JWT为失效。

讨论:

  1. 你这个方案也用到了分布式缓存,也要在缓存中保存数据。这和分布式session或者保存所有的JWT的方案性质不是一样的吗?

    形式上虽然相同,但是保存数据的数量级差别很大。其它两种方案需要保存当前活动用户的全集,而本方案只保存不安全的JWT。相信通常情况下出现token泄露和密码重置的频率是比较低的。需要撤销的JWT占整个活动用户的百分比很小。

    此外JWT只在黑名单中保存一个过期周期,此后就会被删除,进一步控制了黑名单的增长。这样黑名单就可以装载到服务器的内存中,协助完成JWT的本地校验。而无需每次校验时要访问远端服务。

  2. 为什么多此一举的新增一个“groupId”,直接将需要作废的JWT放到黑名单中不就行了吗?

    1) JWT本身比较长,使用较短的“groupId”可以加快黑名单的查询速度。

    2) 若系统不限制用户同一时间能申请的JWT数量。那么可能遇到用户在短时间内恶意请求大量Token的情况。这些Token都放到黑名单中会导致黑名单数量迅速膨胀。使用“groupId”则可以避免这种不可控情况。

  3. 你这个方案又要分布式缓存,又要做黑名单的实时同步。整个方案实施的复杂性似乎超过了分布式session,用它代替分布式session会不会得不偿失?

    1)在一个稍具规模的分布式系统中,分布式缓存、系统总线都是必备的组件。利用这些现有组件可以设计多种方案做数据同步。所以方案看似复杂,实现起来还是不难的。

    2)每个系统侧重的性能指标各有不同。本方案的JWT校验的计算和查询都是在本地内存中完成,不需要依赖远端服务。能够缩短请求的响应时间。对于强调低延迟响应的系统还是比较合适的。

spring cloud实战与思考(四) JWT之Token主动失效的更多相关文章

  1. spring cloud实战与思考(二) 微服务之间通过fiegn上传一组文件(上)

    需求场景: 微服务之间调用接口一次性上传多个文件. 上传文件的同时附带其他参数. 多个文件能有效的区分开,以便进行不同处理. Spring cloud的微服务之间接口调用使用Feign.原装的Feig ...

  2. spring cloud实战与思考(一) spring config全局配置方案设计

    “spring cloud”的配置中心工具“spring cloud config”提供了分布式系统配置文件集中管理解决方案.该工具功能强大,实现也很简单.网上可以搜索到很多开发教程和用例.本文并不是 ...

  3. spring cloud实战与思考(五) JWT之携带敏感信息

    需求: 需要将一些敏感信息保存在JWT中,以便提高业务处理效率. 众所周知JWT协议RFC7519使用Base64Url对Header和Payload的Json字符串进行编解码.A JWT is re ...

  4. spring cloud实战与思考(三) 微服务之间通过fiegn上传一组文件(下)

    需求场景: 用户调用微服务1的接口上传一组图片和对应的描述信息.微服务1处理后,再将这组图片上传给微服务2进行处理.各个微服务能区分开不同的图片进行不同处理. 上一篇博客已经讨论了在微服务之间传递一组 ...

  5. [Spring Cloud实战 | 第六篇:Spring Cloud Gateway+Spring Security OAuth2+JWT实现微服务统一认证授权

    一. 前言 本篇实战案例基于 youlai-mall 项目.项目使用的是当前主流和最新版本的技术和解决方案,自己不会太多华丽的言辞去描述,只希望能勾起大家对编程的一点喜欢.所以有兴趣的朋友可以进入 g ...

  6. Spring Cloud实战 | 最终篇:Spring Cloud Gateway+Spring Security OAuth2集成统一认证授权平台下实现注销使JWT失效方案

    一. 前言 在上一篇文章介绍 youlai-mall 项目中,通过整合Spring Cloud Gateway.Spring Security OAuth2.JWT等技术实现了微服务下统一认证授权平台 ...

  7. Spring Cloud实战 | 最八篇:Spring Cloud +Spring Security OAuth2+ Axios前后端分离模式下无感刷新实现JWT续期

    一. 前言 记得上一篇Spring Cloud的文章关于如何使JWT失效进行了理论结合代码实践的说明,想当然的以为那篇会是基于Spring Cloud统一认证架构系列的最终篇.但关于JWT另外还有一个 ...

  8. Spring Cloud实战之初级入门(四)— 利用Hystrix实现服务熔断与服务监控

    目录 1.环境介绍 2.服务监控 2.1 加入依赖 2.2 修改配置文件 2.3 修改启动文件 2.4 监控服务 2.5 小结 3. 利用hystrix实现消费服务熔断 3.1 加入服务熔断 3.2 ...

  9. Spring Cloud实战 | 第九篇:Spring Cloud整合Spring Security OAuth2认证服务器统一认证自定义异常处理

    本文完整代码下载点击 一. 前言 相信了解过我或者看过我之前的系列文章应该多少知道点我写这些文章包括创建 有来商城youlai-mall 这个项目的目的,想给那些真的想提升自己或者迷茫的人(包括自己- ...

随机推荐

  1. 1115 洛谷luogu最大子段和

    题目描述 给出一段序列,选出其中连续且非空的一段使得这段和最大. 输入输出格式 输入格式: 第一行是一个正整数NNN,表示了序列的长度. 第二行包含NNN个绝对值不大于100001000010000的 ...

  2. nodeJS---URL相关模块用法(url和querystring)

    nodeJS---URL相关模块用法(url和querystring) 一: URL模块: URL模块用于解析和处理URL的字符串,提供了如下三个方法: 1. parse 2. format 3. r ...

  3. Android学习之基础知识十—内容提供器(Content Provider)

    一.跨程序共享数据——内容提供器简介 内容提供器(Content Provider)主要用于在不同的应用程序之间实现数据共享的功能,它提供了一套完整的机制,允许一个程序访问另一个程序中的数据,同时还能 ...

  4. SQL2005中的事务与锁定(九)-(2)- 转载

    -------------------------------------------------------------------------- Author : HappyFlyStone -- ...

  5. Luogu4249 WC2007 石头剪刀布 费用流

    传送门 考虑竞赛图三元环计数,设第\(i\)个点的入度为\(d_i\),根据容斥,答案为\(C_n^3 - \sum C_{d_i}^2\) 所以我们需要最小化\(\sum C_{d_i}^2\) 考 ...

  6. Luogu P2421 [NOI2002]荒岛野人

    最近上课时提到的一道扩欧水题.还是很可做的. 我们首先注意到,如果一个数\(s\)是符合要求的,那么那些比它大(or 小)的数不一定符合要求. 因此说,答案没有单调性,因此不能二分. 然后题目中也提到 ...

  7. Docker管理工具 - Swarm部署记录

    之前介绍了Docker集群管理工具-Kubernetes部署记录,下面介绍另一个管理工具Swarm的用法,Swarm是Docker原生的集群管理软件,与Kubernetes比起来比较简单. Swarm ...

  8. B. Vova and Trophies

    链接 [https://codeforces.com/contest/1082/problem/B] 题意 给你一个包含GS的字符串,只允许交换一次任意不同位置的字符,问最长的连续G串是多少 分析 很 ...

  9. 美食应用 吃了么 beta 测试报告

    为了更好的测试我们应用的兼容性和性能,我们借助了网上的平台Testin云测和百度MTC平台来测试我们的应用,一下是我们的测试结果. 一.兼容性测试 我们对119台终端机器进行了测试,通过测试的有99台 ...

  10. Linux内核分析第一次学习报告

    Linux内核分析第一次学习报告 学生 黎静 学习内容 1.存储程序计算机工作模型 冯诺依曼体系结构:核心思想为存储程序计算机. CPU抽象为for循环,总是执行下一条指令,内存保存指令和数据,CPU ...