我们正在使用 React/Redux 前端开发 Spring 应用程序。我们成功地将其与 Keycloak 身份验证服务集成。但是,我们在访问令牌超时后遇到了不需要的行为。我们的 restMiddleware 看起来像这样(简化):
function restMiddleware() {
return (next) => async (action) => {
try{
await keycloak.updateToken(5);
res = await fetch(restCall.url, {
...restCall.options, ...{
credentials: 'same-origin',
headers: {
Authorization: 'Bearer ' + keycloak.token
}
}
});
}catch(e){}
}
问题是,在令牌过期并执行 updateToken() 后,异步函数不会停止并在收到新访问令牌之前立即调用 fetch()。这当然会阻止 fetch 请求成功并导致响应代码为 401。updateToken() 返回一个 Promise,所以我看不出为什么 await 不起作用,这肯定正在发生。
我确认函数 inupdateToken().success(*function*)
将在成功刷新令牌后执行并将 fetch() 放入其中可以解决问题,但是由于我们的中间件构造,我无法这样做。我开发了这个解决方法:
function refreshToken(minValidity) {
return new Promise((resolve, reject) => {
keycloak.updateToken(minValidity).success(function () {
resolve()
}).error(function () {
reject()
});
});
}
function restMiddleware() {
return (next) => async (action) => {
try{
await refreshToken(5);
res = await fetch(restCall.url, {
...restCall.options, ...{
credentials: 'same-origin',
headers: {
Authorization: 'Bearer ' + keycloak.token
}
}
});
}catch(e){}
}
它有效,但并不优雅。
问题是:为什么第一个解决方案不起作用?为什么我不能等待 updateToken() 而必须使用 updateToken().success() 代替?
我怀疑这可能是一个错误,并确认这是这个问题的主要目的。