We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
移动端场景下,鉴权的方案是基于 token。至于该 token 生成方案,在此不做具体介绍。本文主要介绍处理 token 过期时的实现方案。
token
token过期,我们需要在过期时刷新该token
而我们需要注意的是:
简言之,根据token约定的有效时间,每次用到token之前查看token是否超过有效时间,在有效期内的话就直接使用,否则需要刷新
这种刷新方案存在一个问题,后端可能由于某种原因保存的session丢失,或者客户端保存的有效时间丢失。
session
根据之前梳理的需求,一一解答
1、 刷新时机
后端响应到达客户端时,根据具体的状态码判断是否过期,即是否需要刷新
2、 并发保证不重复刷新
使用锁机制,在刷新 token 过程中,该锁处于占用状态,即其他请求到达时,不会执行刷新。刷新完,该锁释放。
3、 刷新完,之前的请求重新执行
通过队列的方式保存之前的请求,待token刷新完,再执行队列中的请求。
// 假设存在请求方法为request, 可替换成任意request库 // 刷新token的锁 let isRefreshToken = false // 保存原请求的队列 let subscribers = [] // token刷新完,队列中的请求执行 const onTokenRefreshed = token => { subscribers = subscribers.forEach(callback => callback(token)) subscribers = [] } // 向队列中添加原请求 const addSubscribers = callback => subscribers.push(callback) request(url, options) .then(response => { // 假设token过期时的code为401 if(response.statusCode === 401) { // 未占用锁 if(!isRefreshToken) { // 刷新前占用锁 isRefreshToken = true const { token } = await refreshToken() // 刷新完释放锁 isRefreshToken = false // 执行队列中的原请求 onTokenRefreshed(token) } // 原请求加入缓冲队列 const retryOriginRequest = new Promise(resolve => { addSubscribers(token => { resolve(request(url, { ...options, token })) }) }) return retryOriginRequest } })
The text was updated successfully, but these errors were encountered:
No branches or pull requests
背景
移动端场景下,鉴权的方案是基于
token
。至于该token
生成方案,在此不做具体介绍。本文主要介绍处理token
过期时的实现方案。需求梳理
而我们需要注意的是:
方案
这种刷新方案存在一个问题,后端可能由于某种原因保存的
session
丢失,或者客户端保存的有效时间丢失。根据之前梳理的需求,一一解答
1、 刷新时机
2、 并发保证不重复刷新
3、 刷新完,之前的请求重新执行
具体实现
The text was updated successfully, but these errors were encountered: