iOS 使用刷新的身份验证令牌处理请求

iOS Handling requests with refreshed authentication tokens

我正在开发 iPhone 应用程序,我正在使用 Google Plus SDK (GPPSignIn) 获取和刷新身份验证令牌。

这些令牌持续 1 小时。当我使用过期令牌发出请求时,我正在使用的 Web 服务 returns 一个特定的 http 响应代码,以便我知道我的令牌已过期。

收到我的令牌已过期的响应后,我调用刷新身份验证令牌。现在我想用新令牌重复对 Web 服务的请求。我想在我的服务器请求对象中完成这一切。

如果我自己对整个工作进行编程,我可以将令牌刷新请求与 Web 服务器请求内联,当令牌请求完成后,我可以继续 Web 服务器请求。但是由于令牌工作是通过 Google Plus SDK 完成的,并且他们使用委托模型来传达身份验证请求的完成,所以我不知道如何在令牌完成之前将请求保存到 Web 服务已刷新。

目前我正在尝试一个 "pretty bad" 想法,如下所示,我尝试将我的请求放入一个新线程,然后让该线程休眠一段时间,此时它醒来,我们希望新令牌可用。但必须有更好的方法!

             if (error !=nil && error.code == NSURLErrorUserCancelledAuthentication) {
             //special handling of 401, which may be a Google Auth token failure.
             // if it is, then let's go get a new token.

                 User *client = [[User alloc] init];

                 if(client.email != nil && client.password != nil){

                     if (client.accountType == AuthTypeGoogle) {
                         NSLog(@"attempt to get a new token");

                         // request new token
                         [client silentGoogleAuthentication];

                         //repeat request
                         if (repeatableRequest) {
                             dispatch_async(repeatQueue, ^{
                                     [NSThread sleepForTimeInterval:4];
                                     NSLog(@"sleepytime");
                                     [self assignCredentialstoRequest];
                                     [self makeRequest:notificationName repeatableRequest:false];

                             });

                         }
                     }
                 }
             }

如有指点,我们将不胜感激。我查看了一些 iOS 令牌刷新票,我看到了很多陈旧的问题,但是 none 有一个可行的解决方案。

所以在思考这个问题之后,我意识到了一些事情。

  1. 我真正想要的是拥有 [客户端 silentGoogleAuthentication]; 调用内联完成所有处理。进一步深入研究代码,我发现即使它是 GPPSSignIn trySilentAuthentication 支持委托,但它在完成自身处理时也是 returns 布尔值。
  2. 我的进程已经 运行 在主线程之外,所以委托对我来说价值很小。
  3. GPPSSign 使用共享实例,因此如果处理完成,我可以调用共享实例并直接访问结果。

有了这两条信息,我就能够 [客户端 silentGoogleAuthentication]; 调用捕获 trySilentAuthentication 调用的结果,然后将结果分配到代码中的正确位置,然后只是 return 初始调用 [client silentGoogleAuthentication] 的函数的布尔值并继续。像这样:

    // Try signing in silently so user doesn't have to be prompted again
BOOL authResponse = [signIn trySilentAuthentication];
if (authResponse) {
    NSLog(@"successful auth");
    NSLog(@"idToken is %@", [GPPSignIn sharedInstance].idToken);
    self.accountType = AuthTypeGoogle;
    self.password = [GPPSignIn sharedInstance].idToken;
    [self updateCredentials];
    return true;
} else {
    return false;
}