首页 学海无涯 .NET进阶 .NET Core WebAPI 认证授权之JWT(四):JWT续期问题
.NET Core WebAPI 认证授权之JWT(四):JWT续期问题
摘要 了解JWT原理后,可以知道JWT没有滚动过期时间的功能。如果过期时间过长,Token容易暴露,引发安全问题;如果过期时间过短,频繁登录影响用户体验。如何让Token在快过期时刷新过期时间?

问题背景

使用JWT实现一种会话管理的场景:用户使用账号密码登录后,在使用程序期间登录一直有效,最好是几天内不需要重新登录,在长时间没有使用后,才需要用户重新使用账号密码登录。 

这涉及到JWT的续期问题,通过《.NET Core WebAPI 认证授权之JWT(一):JWT介绍》一篇中,可以了解到JWT原文中包含了过期时间,如果过期时间更改了JWT 原文就会改变,也就是说一个Token只能有一个固定的失效时间,无法做到滚动过期,这意味着一到过期时间,用户就需要输入账号密码重新登录。如何解决JWT的续期问题

明确需求和问题过后,我们要做的就是在用户无感知的情况下刷新Token,使用Token有效期延长,最好是实现一段时间内免登录。

解决方案:

1.将Token设置一个长时间的有效期

长时间有效的话大多数情况下,用户就不会面临使用的时候突然重新登录,且过几天Token依然有效。但是,如果恰好在Token过期前几分钟客户开始使用客户端,那没过几分钟也还是需要重新登录。此外使用同一个Token,容易暴露或者带来其他安全问题

作用:不完全解决续期问题,不完全实现长时间免登录。(不过期就是最好的续期)

缺点:安全性、用户体验

2.客户端每次请求,都刷新Token,返回一个新的Token

简单粗暴,大多数下用户在使用期间不会突然重新登录,但是Token有效期内没有请求,也会重新登录,几天后就更不用说了。此外过期的Token无法清除,依然有效,以及每次请求生成Token,性能开销太大。

作用:不完全解决续期问题,无法解决免登录问题。

缺点:太空垃圾、性能损耗、用户体验

3.在Token快要过期前一段时间内,客户端的任意请求都生成一个新的Token

这个时间如果设置过短,恰好在那么这段时间里,客户端没有发起请求,就不能获取到新Token。这个时间设置过长,又会造成过期Token无法清除,刷新频繁(在这个时间无限长的情况下,就成了第2点的情况了)

作用:不完全解决续期问题,无法解决免登录问题。

缺点:用户体验、太空垃圾

4.将Token状态缓存在Redis中,缓存的时间大于Token过期时间。当Token过期时,去判断缓存是否过期,如果缓存没过期则刷新Token返回给前端

违背了JWT的无状态设计,和普通Token或者Session就没什么区别。

作用:解决续期问题,实现一段时间内免登录。

缺点:违背无状态设计

5.模仿oauth2的设计,用户登录时,后端返回两个Token:access_token和refresh_token

access_token用于访问API接口,refresh_token用于刷新token。access_token一般设置一个较短的时间,refresh_token可以设置长时间。当access_token过期,前端再使用refresh_token调用相关接口,获取新的access_token和refresh_token,使用新的access_token再次请求。但旧的refresh_token依然有用,形成太空垃圾,且流程太过复杂。PS:两个Token都使用JWT的无状态设计。

作用:解决续期问题,实现一段时间内免登录。

缺点:流程复杂、太空垃圾

还有其他比如:token设置到半夜用户少的时候过期,这个不用多说。

可以看出真正解决问题的第4点第5点,其实上述几种解决方案,都有缺陷都无法完全实现我们的需求。

第4点其实完全违背了JWT的无状态设计,失去了使用JWT的意义。

第5点似乎是最可取的,解决了jwt有效时间过短用户体验差的问题,也解决了有效时间过长引起的安全问题,同时不违反JWT的无状态设计,但依然存在太空垃圾,流程复杂等情况!

此外第5点可能还有如下问题:

①refresh_token的有效时间也很长,发生泄漏后等同于access_token也同样泄露。

在这里只能找到个相对安全的说法来解释:access_token是访问api接口的token,会频繁使用,泄露风险大,而refresh_token仅用于刷新access_token,使用频率小,相对安全。

②前端无感知刷新

我们的目的是使用户无感知刷新,其实目的已经达到,如果还想让前端无感知刷新,很抱歉,目前没找到!试过很多种,都违背refresh_token设计初衷!

名称释义

太空垃圾:指刷新或重新登录生成新的Token后,旧的Token被废弃,但无法清理,依然有效,称之为太空垃圾。

JWT无状态设计:指服务端没有保存请求的客户端信息,JWT自带客户端的各种信息来识别,每次请求相对独立。  

用户无感知刷新:指用户并不知道Token过期了,不需要用户进行任何操作,就实现Token的续期。

前端无感知刷新:指前端不需要对Token过期和刷新做任何处理,就实现Token的续期。

总结

尝试对JWT进行续期,但似乎无法实现无感知刷新过期时间。此外JWT也无法主动进行清理,要使旧的Token失效,除非更改payload和签名的验证,这不现实。

综上所述,JWT不适合会话管理这样的场景

不禁发出一个疑问:我要JWT有何用?

百度了一下,好像还是有用的:在一次性使用场景下,比如:无状态的API、邮箱验证码等需要一定用户标识,但无法篡改,且只在一定时间内有效的操作。

PS:以上纯属个人观点,学艺不精,欢迎各位大佬指教!

附录

JWT系列目录

            《.NET Core WebAPI 认证授权之JWT(一):JWT介绍》

            《.NET Core WebAPI 认证授权之JWT(二):HMAC算法实操》

            《.NET Core WebAPI 认证授权之JWT(三):RSA算法实操》

            《.NET Core WebAPI 认证授权之JWT(四):JWT续期问题》


版权声明:本文由不落阁原创出品,转载请注明出处!

本文链接:http://www.leo96.com/article/detail/65

广告位

来说两句吧
最新评论

暂无评论,大侠不妨来一发?