我们正在使用React/Redux前端开发Spring应用程序。我们成功地将其与Keycloak认证服务整合在一起。但是,在访问令牌超时之后,我们遇到了不需要的行为。我们restMiddleware看起来像这样(简化):Keycloak |在异步函数中不能等待updateToken()
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()被执行后,异步函数不停止,并调用取()立即收到新的访问令牌之前。这当然可以防止获取请求成功并导致代码401的响应。updateToken()返回一个Promise,所以我没有看到为什么await不起作用,这肯定会发生。
我确认函数updateToken().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()呢?
我怀疑这可能是一个错误,并确认这是这个问题的主要目的。
我只是进去看了keycloak.js,在这种方法定义,我可以看到这一点。 updateToken()返回的内容根本不是Promise(来自ECMAScript规范)。这是一个自定义对象,其中只包含keycloak创建者指定的success()和error()函数...“承诺对象”-.- “updateToken方法返回一个承诺对象,该对象只有在令牌已成功刷新,例如,如果不是,则会向用户显示错误。“ 这是非常混乱的,我认为他们不应该使用这个描述。 – BJanusz