如何确保在预检调用之间令牌不会过期?

时间:2017-11-07 11:24:51

标签: javascript keycloak

我正面临Keycloak的间歇性问题。如果用户触发预检API调用并且Keycloak的令牌在该调用与实际API调用之间到期,则预检调用将返回200,但真正的API调用将返回401(因为令牌现已过期)。

事件的流程基本上是:

  1. 用户触发预检API调用,生成OPTIONS请求。
  2. Keycloak的令牌过期并刷新。
  3. 预检请求返回,使用旧的Keycloak令牌发送GET呼叫。
  4. 当旧令牌过期时,API返回401。
  5. 以下是我浏览器的“网络”标签中的内容:

    Example Network tab flow

    如何确保Keycloak令牌在这些事件之间不会过期?

    这是我正在使用的代码:

    async onTokenExpired() {
      this.token = await this.updateToken();
      this.updateHeaders();
    }
    
    updateHeaders() {
      http.setHeaders({
        Authorization: `Bearer ${this.token}`
      });
    }
    
    updateToken() {
      return new Promise((resolve, reject) => {
        this.keycloak.updateToken()
          .success(() => {
            resolve(this.keycloak.token);
          })
          .error(reject);
      });
    }
    

1 个答案:

答案 0 :(得分:0)

好的,我最终解决的问题是每次进行API调用时调用Keycloak的updateToken方法,传递20秒的 minValidity

  

updateToken(minValidity)

     

如果令牌在minValidity秒内到期(minValidity是可选的,如果未指定5则使用),则刷新令牌。如果启用了会话状态iframe,则还会检查会话状态。

     

- Keycloak's updateToken documentation

我的API调用代码现在看起来像这样:

post(...) {
  this.keycloak.updateToken(20).success(() => {
    fetch(...)
  })
}

在伪代码中,这主要做以下事情:

When the post method is called:
  Attempt to update the token if it is going to expire within the next 20 seconds.
  If that is successful (regardless of whether it updated or not), call the API.

我不相信这是一个完美的解决方案,因为我确信可能有一个预检请求执行时间超过20秒的实例,但在这种情况下,这不是这确实是问题的原因,需要在服务器端解决。如果预检请求经常需要超过20秒才能执行,则 minValidity 可以提升到更长的持续时间。 20本身已经非常宽松(默认值为5)。