需求:

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. js之省市区(县)三级联动效果

    省市区(县)三级联动效果,是我们软件开发比较常用的,特别是对一些crm,erp之类,当然也包括其他的后台管理系统,基本都涉及到,今天贴出这个常用的,方便个人复用和大家使用 <!DOCTYPE h ...

  2. ConcurrentHashMap中的putIfAbsent方法的使用以及返回值的含义

    public V putIfAbsent(@NotNull K key, @NotNull V value) putIfAbsent方法主要是在向ConcurrentHashMap中添加键—值对的时候 ...

  3. 11-(基础入门篇)WiFi模块开发,下载运行第一个程序

    https://www.cnblogs.com/yangfengwu/p/9954840.html 第一就是重新刷一下固件,咱们的固件保持一致,有问题好处理 先刷空固件 我用的 所以刷8Mbit的 给 ...

  4. Ionic buid android下的此工程不是一个android项目问题

    今天编译Ionic项目的时候报如下错误,甚是费解,之前一直都是好的 首先去检查了,相关JavaHome的环境变量,确定是好的,java -version 命令没有问题. 经查阅网上的解决方法,思路大都 ...

  5. linux 与 windows 挖门罗币总结

    比特币之前一直很火,初次了解的时候才2000RMB一枚..看不懂哇,错失良机...当然了,看得懂也不买不起..当时还是穷学生. 最近又一直看到黑客利用linux漏洞挖门罗币获利的新闻,决定好生研究一下 ...

  6. Flutter - TabBar导航栏切换后,状态丢失

    上一篇讲到了 Flutter - BottomNavigationBar底部导航栏切换后,状态丢失 里面提到了TabBar,这儿专门再写一下吧,具体怎么操作,来不让TabBar的状态丢失.毕竟大家99 ...

  7. (8)学习笔记 ) ASP.NET CORE微服务 Micro-Service ---- Ocelot网关(Api GateWay)

    说到现在现有微服务的几点不足: 1) 对于在微服务体系中.和 Consul 通讯的微服务来讲,使用服务名即可访问.但是对于手 机.web 端等外部访问者仍然需要和 N 多服务器交互,需要记忆他们的服务 ...

  8. JSP页面<%@ ...%>是什么意思?

    这表示是指令,主要用来提供整个JSP 网页相关的信息,并且用来设定JSP网页的相关属性,例如:网页的编码方式.语法.信息等.起始符号为: <%@终止符号为: %>目前有三种指令:page. ...

  9. VMware vSphere虚拟化-VMware ESXi 5.5组件安装过程记录

    几种主要的虚拟化 ESXi是VMware公司研发的虚拟机服务器,ESXi已经实现了与Virtual Appliance Marketplace的直接整合,使用户能够即刻下载并运行虚拟设备.这为 即插即 ...

  10. 一个数据表通过另一个表更新数据(在UPDAT语句中使用FROM子句)

    在sql server中,update可以根据一个表的信息去更新另一个表的信息. 首先看一下语法: update A SET 字段1=B表字段表达式, 字段2=B表字段表达式   from B WHE ...