钥匙披风|无法等待异步函数中的updateToken() [英] Keycloak | Cannot await on updateToken() in async function

查看:407
本文介绍了钥匙披风|无法等待异步函数中的updateToken()的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们正在开发具有React/Redux前端的Spring应用程序.我们已成功将其与Keycloak身份验证服务集成.但是,访问令牌超时后,我们遇到了不良行为.我们的restMiddleware看起来像这样(简化):

We are developing Spring application with React/Redux frontend. We successfully integrated it with Keycloak authentication service. However, we encountered unwanted behaviour after access token timed out. Our restMiddleware looks like this (simplified):

    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().当然,这会阻止获取请求的成功,并导致代码401的响应.updateToken()返回Promise,所以我看不出为什么await无法对其进行处理,这确实在发生.

The problem is, that after token expires and updateToken() is executed, async function does not stop and invokes fetch() immediately, before new access token is received. This of course prevents fetch request from succeeding and causes response with code 401. updateToken() returns a Promise, so I see no reason why await would not work on it, which certainly is happening.

我确认updateToken().success(*function*)中的函数将在成功刷新令牌后执行,并将fetch()放入其中可以解决该问题,但是由于我们的中间件构造,我无法做到这一点.我开发了这种解决方法:

I confirmed that function in updateToken().success(*function*) will execute after successful token refresh and placing fetch() inside it would solve the problem, but because of our middleware construction I cannot do that. I developed this workaround:

    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){}
    }

它可以工作,但是并不优雅.

And it works, but it is not elegant.

问题是:为什么第一个解决方案不起作用?为什么我不能等待updateToken()而必须使用updateToken().success()代替?

The question is: why the first solution didn't worked? Why I cannot await on updateToken() and have to use updateToken().success() instead?

我怀疑这可能是一个错误,并确认这是此问题的主要目的.

I suspect this might be a bug and to confirm this is the main purpose of this question.

推荐答案

updateToken方法的文档指出,它返回了一个Promise,但实际上它不是可实现的,因此await关键字并不认为它是有效的Promise.我就是这样说的. :)

updateToken method's documentation states that it returns a promise, but it actually isn't a thenable and thus the await keyword does not think it as a valid Promise. This is how I would put it. :)

您的解决方案对我来说似乎很优雅,并且在调用updateToken函数之后,我也做了同样的事情来正确地继续执行Promise链.

Your solution seems elegant to me and I have done the exact same thing also to correctly continue on a Promise chain after calling the updateToken function.

Keycloak JavaScript适配器文档: https://keycloak. gitbooks.io/documentation/securing_apps/topics/oidc/javascript-adapter.html

Keycloak JavaScript adapter documentation: https://keycloak.gitbooks.io/documentation/securing_apps/topics/oidc/javascript-adapter.html

这篇关于钥匙披风|无法等待异步函数中的updateToken()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆