我需要关于如何在我的应用程序中处理OAuth2令牌刷新的建议。
我正在使用grpc向我的api发出http请求,这个api连接了一个oauth2令牌(一小时后过期)。
在启动每个请求之前,我检查令牌:
最新?启动NetworkRequest
过时了?启动RefreshToken->Launch NetworkRequest
似乎一切正常,但在某些情况下,我的客户“丢失”了代币。
问题是,对于在同一时间启动的2个请求a&b,如果令牌过期,它们都将刷新它。
我的服务器将生成一个newtokena,返回它,生成newtokenb(删除newtokena),返回它。
如果newtokena在newtokenb之后到达客户机,那么客户机令牌令牌将不是好的令牌。
我使用了一个信号量来确保一个调用同时进行刷新令牌。
但当我的信号量在等待时,我没有收到服务器的任何响应。

let semaphore: dispatch_semaphore_t = dispatch_semaphore_create(0)

func authenticate(completion: (GRPCProtoCall) -> (Void)) -> GRPCProtoCall {

    // Wait here if authenticate already called
    dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER)

     // If token up to date
    if isOAuth2TokenValid() {
        dispatch_semaphore_signal(semaphore) // Release semaphore
        completion(self.withAuthorization())
        return self
    }

    // Refresh the outdated token
    APIClient.shared.oAuth2AccessTokenRefresh { (response) -> (Void) in
        dispatch_semaphore_signal(semaphore)  // Release semaphore
        completion(self.withAuthorization())
    }

    return self
}

最佳答案

我认为您的dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER)持有您的线程,如果最后一个请求没有响应,您可以在超时的情况下尝试,并在返回self之前将其放置

while semaphore.wait(timeout: DispatchTime.now() + Double(5000000000) / Double(NSEC_PER_SEC)) == DispatchTimeoutResult.success {//time out set to 5 seconds
    print("wait")
}

10-07 22:46