JWT登录过期自动刷新方案与token泄漏解决方案

发布于:2022-12-19 ⋅ 阅读:(1082) ⋅ 点赞:(0)

概念

简单来说JWT就是通过一定规范来生成token,再用解密算法解密token,就可以获取用户信息了。

优缺点

优点:避免重复查库,存储在客户端,不占用服务端资源

缺点:token是经过base64编码,所以可以解码,因此token加密前的对象不应该包含敏感信息(如用户权限、密码等)

关于自动刷新Token

背景:

在前后分离场景下,越来越多的项目使用jwt token作为接口的安全机制,但存在jwt过期后,用户无法直接感知,假如在用户操作页面期间,突然提示登录,则体验很不友好,所以就有了token自动刷新需求

但是这个自动刷新方案,基本都离不开服务端状态存储,JWT推出思想是:去中心化,无状态化,所以有所违背

 方案一:前端控制检测token,无感知刷新

用户登录成功的时候,一次性给他两个Token,分别为AccessToken和RefreshToken
AccessToken有效期较短,比如1天或者5天,用于正常请求
RefreshToken有效期可以设置长一些,例如10天、20天,作为刷新AccessToken的凭证

刷新方案:当AccessToken即将过期的时候,例如提前30分钟,客户端利用RefreshToken请求指定的API获取新的AccessToken并更新本地存储中的AccessToken

核心逻辑
1、登录成功后,jwt生成AccessToken; UUID生成RefreshToken并存储在服务端redis中,设置过期时间
2、接口返回3个字段AccessToken/RefreshToken/访问令牌过期时间戳
3、由于RefreshToken存储在服务端redis中,假如这个RefreshToken也过期,则提示重新登录; 


提问:RefreshToken有效期那么长,和直接将AccessToken的有效期延长有什么区别?

答:RefreshToken不像AccessToken那样在大多数请求中都被使用,主要是本地检测accessToken快过期的时候才使用,
一般本地存储的时候,也不叫refreshToken,前端可以取个别名,混淆代码让攻击者不能直接识别这个就是刷新令牌


缺点:前端每次请求需要判断token距离过期时间
优点:后端压力小,代码逻辑改动不大

方案二:后端存储判断过期时间

后端存储AccessToken,每次请求过来都判断是否要过期,如果快要过期则重新生成新的token,并返回给前端重新存储,比如距离1天就过期的情况,如果用户访问对应的接口则会更新,但假如没访问则token已经过期则需要重新登录


优点:前端改动小,只需要存储响应http头里面是否有新的令牌产生,有的话就重新存储
缺点:后端实现复杂,且泄露后容易存在一直保活状态,且前端会存在并发请求,当并发请求收到多个jwt token时,容易生成多个token混乱使用

JWT令牌token泄露恶意使用-解决方案

使用互联网大厂的产品时经常遇到这个情况

  • 比如阿里云或者淘宝,你现在登录了然后换个网络或者地域就需要重新登录

  • 就是对应的token令牌,不只简单的算法加密,还包括了客户端属性、地理网络位置信息等,一起组成一个token令牌

如何避免token令牌泄露被恶意使用 :IP绑定

生成token的时候,加密的payload加入当前用户ip。

拦截器解密后,获取payload的ip和当前访问ip判断是否同个,如果不是则提示重新登录

优点:服务端无需存储相关内容,性能高,假如用户广州登录,泄露了token给杭州的黑客,依旧用不了

缺点:如果用户用使用过程中ip变动频繁,则操作会经常提示重新登录,体验不友好

当然也可以让用户开启安全模式和非安全模式,让用户自己知道这个情况,一些区块链、比特币交易所里面就会让用户自己选择控制这个token令牌安全是否和ip、终端、地理网络信息进行绑定

{
                id:888,
                name:'绾绾',
                ip:“127.0.0.1”
                expire:10000
            }
            
            funtion 加密(object, appsecret){
                xxxx
                return base64( token);
            }

            function 解密(token ,appsecret){
					
                xxxx
                //成功返回true,失败返回false
            }

本文含有隐藏内容,请 开通VIP 后查看

网站公告

今日签到

点亮在社区的每一天
去签到