我们有一个react-redux应用程序,它在每次页面加载时使用多个API调用来获取数据。该应用程序遵循 OAuth2 协议(protocol)。它有一个经常过期的访问 token 和一个用于获取新访问 token 的刷新 token 。 如果使用过期的访问 token 进行 API 调用,则会收到 401 错误,并显示错误消息“API token 已过期”。然后我们需要从身份验证服务器获取新的 token 。
我的问题是这样的: 当页面加载时,假设调度了 8 个 API 调用。我们收到 3 个成功的 200,但从第 4 个响应开始,我们收到 401“API token 已过期”。此时,我想将所有已发出但未收到响应或收到 401 错误的 API 调用放入队列中,直到刷新访问 token 。成功刷新访问 token 后,我想重新执行队列中保存的 API 调用。我怎样才能实现这个目标?
在网上寻找这个,我发现 redux-saga 可能有效,但没有看到任何迹象表明它可以用于此用例。
最佳答案
我也曾经处理过这种情况。这是我的解决方案:
/**
* Connect to API
*/
export const makeRequest = (args) => {
const request = fetch(args)//example
return _retryRequestIfExpired(request, args)
}
/**
* Fake get access token.
*/
const _getNewAccessToken = () => {
return new Promise((resolve, reject) => {
resolve('xyz')
})
}
const _retryRequestIfExpired = (request, args) => {
return request.catch(error => {
if (error === 'abc') {//Any reason you want
return _refreshAccessToken()
.then(newAccessToken => {
const updateArgs = {
...args,
headers: {
'Authorization': newAccessToken
}
}
//Retry with new access token
return makeRequest(updateArgs)
})
}
throw error
})
}
/**
* Important
*/
let _isRefreshingToken = false
let _subscribers = []
const _subscribe = subscriber => {
if (typeof subscriber !== 'function' || _subscribers.indexOf(subscriber) !== -1) {
return false
}
_subscribers = [].concat(_subscribers, [subscriber])
}
const _broadcast = (error = null, data) => {
_isRefreshingToken = false
_subscribers.forEach(subscriber => {
subscriber(error, data)
})
_subscribers = []
}
const _refreshAccessToken = () => {
if (_isRefreshingToken) {//If a request is creating new access token
return new Promise((resolve, reject) => {
const subscriber = (error, accessToken) => {
if (error) {
return reject(error)
}
return resolve(accessToken)
}
_subscribe(subscriber)
})
}
_isRefreshingToken = true
return _getNewAccessToken()
.then(accessToken => {
_broadcast(null, accessToken)
return accessToken
})
.catch(error => {
_broadcast(error)
throw error
})
}
/**
* End Important
*/
这样,只有第一个请求才会真正创建新的访问 token ,其余请求将暂时停止,直到创建新的访问 token 。
关于reactjs - 如何在刷新访问 token 时暂停和重新启动react-redux应用程序中的API调用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52409635/