工作--JWT实战总结

公司的登录模块也从Session切换到JWT挺长一段时间了,抽时间来总结一下遇到的问题以及解决方案.

为什么用JWT?

在JWT之前,公司是利用传统的Session来实现登录状态的保持,分布式下则利用Redis实现Session共享集中管理,共享集中管理会带来登录强依赖Redis,然而公司的Redis确实不太稳定,导致一蹦或者网络抖动就会使得用户受到影响,另外一点就是用户的Session存在redis中没有设置超时时间,其格式为 UUID - 用户信息JSON串,这个是大坑,导致Redis等我接手时已经膨胀到了30G之多,因此在大家强烈要求下JWT的改造就此开始. 之所以选择JWT,因为其不需要服务端存储,也就是可以直接下掉Redis,另外其playload可以存储不少关键信息并且小巧接入成本极小.

会有哪些问题?

Token中存哪些必要东西?

Jwt Token的playload实际上只是base64编码了一层,其被解码后可以查看到具体的文本信息,因此不能存私密性的东西.建议存储 id,username,expire,version等一些不是很关键的数据.至于version有什么用,后面吊销的时候在讨论.

Token何时下发?

  1. 登录下发新token,原token实际上并没有失效,保证多端登录没问题.
  2. Token剩余有效时长大于可续期时长(根据业务平台自己定)时重新下发.举个栗子针对WEB端Token24小时有效,当有效时间小于12小时刷新Token,也就是当用户连续12小时没操作网站才会被退出.
  3. 修改或者重置密码时下发新Token,并吊销之前的Token

Token如何吊销?

JWT不需要在服务端存储,因此吊销是个大问题,无法吊销的话就会出现用户密码被盗,即使用户修改了密码,其他人也并不会立即失效,这点在安全性很高的地方几乎是不允许的情况.因此吊销是必要的. 吊销方案有存储黑名单Token,个人觉得不是很好,一长串的东西扔哪都不合适啊,因此想着存储用户的version在Token中,当用户修改或重置密码后期版本自增,那么当请求到来时与Token中version进行对比,不一致则直接拒绝访问,实现了吊销. 缺点也很明显每次请求到来都需要去DB或者缓存取出用户的版本,然后与Token中的version进行一次判断,这个看业务容忍度来取舍了.个人建议放Redis的中,即使1000w数据内存占用也是非常少的,而且对于大多数业务来说这个并不需要强依赖,Redis挂了则根据异常以及Token的到期时间自由选择直接放行还是拒绝.

Token签名秘钥如何替换

Token为了保证其可靠性,因此必须有签名串并且还需要HTTPS防止中间人攻击,因此秘钥更换也是必须的. 所采取的方案是用一个定长为2的secret[2]数组来保存秘钥,秘钥是存储在配置中,下发时使用secret[0],验签时也从secret[0]开始验签,验签失败则使用secret[1]验签,当然为了加快替换流程,secret[1]验签成功后需要重新下发secret[0]签名的Token,在运行一段时间后则可以把secret[0]替换为secret[1],重新增加新秘钥放入secret[0]中.因为秘钥都是写在配置中的,因此每次只需要重新发下配置即可.

如何与现有结构兼容?

兼容实际上判断有没有下发Token,没有则使用原本Session的验证,在验证成功后下发Token,保证下次请求可以使用Token验证,那么这样跑一段时间则能保证绝大部分活跃用户切换到了Token流程.

旧Redis如何清理?

旧Redis中存储着大量key为UUID并且没有失效时间的字符串,清理只能扫描所有的key,然后判断是不是UUID的格式,判断是否有失效时间,没有则删除.那么会有以下问题

列出所有Key

  1. KEYS 生产上禁止使用的命令,其复杂度是O(N)也就是全遍历,会带来性能问题.
  2. SCAN迭代模式, SCAN每次返回一定量的key集合,并且返回下次迭代的游标,是可以在生产环境上使用的命令,因此最佳选择.

清理操作

清理脚本就很简单的扫描出key,判断是否为UUID格式,然后利用TTL命令判断是否设置过期时间,没设置则删除.注意该清理要在Token替换了大部分Session之后进行,保证对当前使用Session的用户无太大影响.

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏魏艾斯博客www.vpsss.net

解决 Winscp 不显示隐藏文件的办法

平时魏艾斯博客使用 Winscp 当做 SFTP 工具, 我们也经常遇到要修改.htaccess 和.user.ini 等等用.开头或者其他特殊扩展名文件,在 ...

4469
来自专栏Python小白进阶之旅

还在找远控?来看我用十几行python代码写个简易远程控制

刚开始学习编程的同学可能经常会问:“我学了这个干什么用?买菜的时候掏出电脑来编个程序算算多少钱?”

53313
来自专栏北京马哥教育

一万两千字长文,六大问题为你解读计算机

1描述计算机的组成及其功能 电子计算机,亦称电脑,是一种利用电子学原理,根据一系列指令对数据进行处理的工具 计算机及其组成 计算机是什么       电子计...

37410
来自专栏一只程序汪的自我修养

使用requirejs编写模块化代码

2435
来自专栏有趣的django

Django REST framework+Vue 打造生鲜超市(十二) 十三、首页、商品数量、缓存和限速功能开发

十三、首页、商品数量、缓存和限速功能开发  13.1.轮播图接口实现 首先把pycharm环境改成本地的,vue中local_host也改成本地  (1)goo...

6897
来自专栏*坤的Blog

智动大闯关密码游戏记录

这个是之前玩过的一个网页闯关游戏,只是玩过,但是卡在一个关卡没有通过,希望寻求一下帮助,智动大闯关。

9142
来自专栏数据小魔方

word多文档合并技巧

今天要跟大家安利一些word多文档合并的技巧! 经常要处理word文档的小伙伴儿们,是不是也遇到过这样的难题。 偶尔要把一大堆的word文本文档,弄到一个文档...

3436
来自专栏信安之路

ourphp 前台注册登入前台某用戶

在function\api\ourphpuser\ourphp_system.php该文件存在用户login函数

1180
来自专栏ChaMd5安全团队

Flare-On 2018 writeup(下)

后门下载器加载库函数从ldr链表中遍历模块和模块函数,使用Hash来获取API定位,此后的API都用这种方法遍历,由于是病毒经典使用方法,可以搜到hash表,没...

1174
来自专栏python爬虫实战之路

新浪微博PC端模拟登陆

本来给自己定了个2018的目标,平均每月写两篇文章,现在已经快三月了,第一篇稿子才憋出来,惭愧呀,直入主题吧,今天给大家带来的是新浪微博PC端的模拟登陆。

6033

扫码关注云+社区

领取腾讯云代金券