spring cloud实战与思考(四) JWT之Token主动失效
需求:
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主动失效的更多相关文章
- spring cloud实战与思考(二) 微服务之间通过fiegn上传一组文件(上)
需求场景: 微服务之间调用接口一次性上传多个文件. 上传文件的同时附带其他参数. 多个文件能有效的区分开,以便进行不同处理. Spring cloud的微服务之间接口调用使用Feign.原装的Feig ...
- spring cloud实战与思考(一) spring config全局配置方案设计
“spring cloud”的配置中心工具“spring cloud config”提供了分布式系统配置文件集中管理解决方案.该工具功能强大,实现也很简单.网上可以搜索到很多开发教程和用例.本文并不是 ...
- spring cloud实战与思考(五) JWT之携带敏感信息
需求: 需要将一些敏感信息保存在JWT中,以便提高业务处理效率. 众所周知JWT协议RFC7519使用Base64Url对Header和Payload的Json字符串进行编解码.A JWT is re ...
- spring cloud实战与思考(三) 微服务之间通过fiegn上传一组文件(下)
需求场景: 用户调用微服务1的接口上传一组图片和对应的描述信息.微服务1处理后,再将这组图片上传给微服务2进行处理.各个微服务能区分开不同的图片进行不同处理. 上一篇博客已经讨论了在微服务之间传递一组 ...
- [Spring Cloud实战 | 第六篇:Spring Cloud Gateway+Spring Security OAuth2+JWT实现微服务统一认证授权
一. 前言 本篇实战案例基于 youlai-mall 项目.项目使用的是当前主流和最新版本的技术和解决方案,自己不会太多华丽的言辞去描述,只希望能勾起大家对编程的一点喜欢.所以有兴趣的朋友可以进入 g ...
- Spring Cloud实战 | 最终篇:Spring Cloud Gateway+Spring Security OAuth2集成统一认证授权平台下实现注销使JWT失效方案
一. 前言 在上一篇文章介绍 youlai-mall 项目中,通过整合Spring Cloud Gateway.Spring Security OAuth2.JWT等技术实现了微服务下统一认证授权平台 ...
- Spring Cloud实战 | 最八篇:Spring Cloud +Spring Security OAuth2+ Axios前后端分离模式下无感刷新实现JWT续期
一. 前言 记得上一篇Spring Cloud的文章关于如何使JWT失效进行了理论结合代码实践的说明,想当然的以为那篇会是基于Spring Cloud统一认证架构系列的最终篇.但关于JWT另外还有一个 ...
- Spring Cloud实战之初级入门(四)— 利用Hystrix实现服务熔断与服务监控
目录 1.环境介绍 2.服务监控 2.1 加入依赖 2.2 修改配置文件 2.3 修改启动文件 2.4 监控服务 2.5 小结 3. 利用hystrix实现消费服务熔断 3.1 加入服务熔断 3.2 ...
- Spring Cloud实战 | 第九篇:Spring Cloud整合Spring Security OAuth2认证服务器统一认证自定义异常处理
本文完整代码下载点击 一. 前言 相信了解过我或者看过我之前的系列文章应该多少知道点我写这些文章包括创建 有来商城youlai-mall 这个项目的目的,想给那些真的想提升自己或者迷茫的人(包括自己- ...
随机推荐
- js删除数组元素、清空数组的简单方法
一.清空数组 ? 1 2 3 var ary = [1,2,3,4]; ary.splice(0,ary.length);//清空数组 console.log(ary); // 输出 [],空数组,即 ...
- mysql获取表中数据行数
获取单个表的行数 使用count(*)或者count(1) SELECT count(1) AS count FROM table_name; 执行结果 获取两个表的行数 使用union组合每个sel ...
- 使用jdom进行xml解析,网络抓包
最近再做一个项目,使用到了jdom进行xml解析,为了方便记忆,现在保存在这里 package bboss; import java.io.FileInputStream; import java.i ...
- C# 程序默认使用管理员权限(转载)
1.从A程序启动B程序,当B程序需要管理员权限的时候代码如下 A程序里面启动B程序的代码如下 ProcessStartInfo startInfo = new ProcessStartInfo(); ...
- 设计模式:装饰模式(decorate)
还是那几句话: 学无止境,精益求精 十年河东,十年河西,莫欺少年穷 学历代表你的过去,能力代表你的现在,学习代表你的将来 废话不多说,直接进入正题: 今天学习了装饰模式,但是代码看不太懂,于是我将装饰 ...
- NOIp2014提高组初赛错题简析
总体分析 \(89pts\),粗略来看选择题错的比较多,\(-6pts\).同时又是尿性的填空杀扣了\(5pts\). 不过后面的两大题全对了还是可喜可贺 错题精析 单项选择T8 编译器的主要功能是( ...
- ASP.NETZERO 开发者指南-目录篇
前面的话 此教程适用于 ASP.NET MVC 5.x & Angularjs 1.x 的ABP框架(收费需要授权) 所以有能力的朋友还是希望你们多多支持 土牛.购买链接:https://w ...
- Webpack 2 视频教程 002 - NodeJS 安装与配置
原文发表于我的技术博客 这是我免费发布的高质量超清「Webpack 2 视频教程」. Webpack 作为目前前端开发必备的框架,Webpack 发布了 2.0 版本,此视频就是基于 2.0 的版本讲 ...
- NB-IOT_BC95_B5常用AT指令集
.AT+<cmd>=? 测试命令,用于向模块询问支持的设置项目. .AT+<cmd>? 读取命令,用于让模块上报某个命令代表的设置项当前的值. .AT+<cmd>= ...
- 牛客第二场-J-farm-二维树状数组
二维树状数组真的还挺神奇的,更新也很神奇,比如我要更新一个区域内的和,我们的更新操作是这样的 add(x1,y1,z); add(x2+1,y2+1,z); add(x1,y2+1,-z); add( ...