我们正在使用React/Redux前端开发Spring应用程序。我们已成功将其与Keycloak身份验证服务集成。但是,访问 token 超时后,我们遇到了不良行为。我们的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){}
}
问题是,在 token 过期并执行了updateToken()之后,异步函数不会停止,并在接收到新的访问 token 之前立即调用fetch()。当然,这会阻止获取请求的成功,并导致代码401的响应。updateToken()返回Promise,所以我认为没有任何原因使wait不能正常工作,这肯定正在发生。
我确认
updateToken().success(*function*)
中的函数将在成功刷新 token 后执行,并将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()?
我怀疑这可能是一个错误,并确认这是此问题的主要目的。
最佳答案
updateToken
方法的文档指出,它返回了Promise
,但实际上不具备then
的功能,因此await
关键字并不认为它是有效的Promise
。我就是这样说的。 :)
您的解决方案对我来说似乎很优雅,在调用Promise
函数之后,我也做了完全相同的事情以正确继续在updateToken
链上进行操作。
Keycloak JavaScript适配器文档:https://keycloak.gitbooks.io/documentation/securing_apps/topics/oidc/javascript-adapter.html
关于javascript - key 披风|无法等待异步函数中的updateToken(),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/45610720/