代码之家  ›  专栏  ›  技术社区  ›  Siyu Zeeshan Akhter

何时将访问令牌与刷新令牌交换

  •  0
  • Siyu Zeeshan Akhter  · 技术社区  · 7 年前

    在短期访问令牌过期后(服务器返回401),客户端必须使用刷新令牌请求一个新的令牌。

    要在iOS(使用AFNetworking)或Android(使用Volley)应用程序中实现它,我认为网络管理器必须能够检测返回的401错误,然后将请求发送到auth服务器。

    问题在于网络的并发使用。考虑访问已经过期的情况,应用程序发送2个请求:Req1和100MS之后,Req2。在时间轴上绘制,如下所示:

    req1 --> 401 --> (refresh req) --> OK, new access and fresh tokens --> retry req1
      req2 --> 401 --> (refresh req) --> 403, wrong refresh token
    

    所以我的问题是

    这一实施是否朝着正确的方向发展?或者在收到401后刷新是错误的?我是否应该在用户启动应用程序时刷新令牌(以减慢应用程序启动速度为代价)

    如何解决并发问题?

    1 回复  |  直到 7 年前
        1
  •  1
  •   Ján HalaÅ¡a    7 年前

    由于您有一个现有的令牌管理器,我将向其中添加一些额外的逻辑(Java):

    class TokenManager {
    
      private String accessToken;
      private CompletableFuture<String> accessTokenRefreshComletableFuture;
    
      public CompletableFuture<String> getAccessToken() {
        if (this.accessToken is expired) {
           // If refreshed accessToken is being requested
           CompletableFuture<String> runningRequestFuture = this.accessTokenRefreshComletableFuture;
           if (runningRequestFuture == null) {
              // For thread safety, this assignment should be synchronized (or made atomic)
              // with the previous reading
              this.accessTokenRefreshComletableFuture = new CompletableFuture<>();
              // Request a fresh access token.
              // When you get a new access token, set the this.accessTokenRefreshComletableFuture 
              // complete and remove its reference from the manager class.
           }
           return runningRequestFuture;
        }
        // Synchronous result
        return CompletableFuture.completedFuture(this.accessToken);
      }
    }
    

    管理器不返回访问令牌,而是返回 CompletableFuture (JavaScript中的承诺-异步结果)。如果需要刷新访问令牌,请首先检查 /token 终结点请求已在运行。如果是的话,把它的 CompletableFuture

    这样,您将始终拥有有效的访问令牌或单个 完全未来