困局
平时做项目早就习惯了,在拦截器中将 accessToken
放入 request header
头中,如果 token
过期,则请求 refreshToken
接口,拿到一个新 token
( babalabala ,还有很多细节 isRereshing and 刷新过程中将新请求的 request 放入队列...)前端刷新token最佳实践
疑问
为什么不能设置一个长有效期的accessToken?
谷百(谷歌百度)大法罗列到的一些结果,无非就这两种:
1、用户体验
(比如用户正在操作一个非常复杂的表单,半个小时后提交了,你提示他token过期,需要重新登录?)
2、安全上
(accessToken如果被劫持,就可以冒充用户操作系统了)
但是仔细想一下,这些解释是站不住脚的,对于用户体验
来说,refreshToken
也是有过期时间的,拿refreshToken
刷新accessToken
,也需要面对refreshToken
过期重新登录的情况。对于安全角度
来讲,https的环境下,放在请求头的accessToken
是不可能被劫持的,退一步讲,就算是http环境,accessToken
被劫持了,refreshToken
不是照样也可以被劫持?
后端答疑
于是找后端大佬解惑:
accessToken
可以是 stateless 的,比如 JWT ,不做吊销,用的时候直接空手验证,不需要访问数据库,refreshToken
存到数据库里,做吊销
翻译成白话就是:accessToken
负责效率,前端带过来直接解密,不查验状态直接用。而 refreshToken
负责安全,每次使用都要查数据库,从而实现服务端注销等操作
我们再来想一想,为什么不设置一个长有效期的token呢?
长有效期的token可能会出现这样的一系列问题:
-
用户修改密码后,之前登录的系统,仍然一直可以用
-
用户退出登录,切换账号登录,除了前端强制删除token重定向到登录页面,更新本地的token,服务器是无法感知用户的注销操作的
总结
accessToken
的存在是为了提升服务端对客户端的请求认证效率,是无状态的,直接解密校验(比如JWT、oauth2),更快,而refreshToken
是跟负责安全的,是需要增删改查数据库表的,两者配合,才会更安全,更高效。(以上内容纯属个人理解,如有偏差的地方,还请大佬指正)