ios – 如何使用GIDSignIn或GIDAuthentication刷新authentication.idToken?

更新2015-10-28 – Release 2.4.0 of Google Sign-In for iOS似乎解决了这个问题,新的GIDAuthentication方法getTokensWithHandler:和refreshTokensWithHandler:必须刷新idToken和accessToken. GIDSignIn方法SignInSilently还刷新两个标记.

我正在使用适用于iOS的AWS Mobile SDK,并且我已使用AWS Cognito Sync sample code作为基础,将Google登录作为Cognito凭据提供程序实施.登录(以及后续静默登录)流程正常运行,登录用户可以按预期访问DynamoDB等AWS资源.

我的问题是user.authentication.idToken在一小时后过期,此时对AWS服务的调用失败并出现身份验证错误.我可以使用刷新user.authentication.accessToken

[self.googleUser.authentication refreshAccessTokenWithHandler:^(NSString *accessToken, NSError *error) {...}

但这不会更新idToken.我也试过打电话

[[GoogleSignIn sharedInstance] signInSilently];

这在第一次在会话中调用时给了我一个有效的idToken,但是虽然它成功完成但它不会在同一会话中的后续调用中刷新idToken.

我一直在检查/转储令牌内容

https://www.googleapis.com/oauth2/v1/tokeninfo?id_token=<idToken>

https://www.googleapis.com/oauth2/v1/tokeninfo?access_token=<accessToken>

我不确定问题是GIDSignIn是不是在更新idToken,还是AWS应该以某种方式使用refreshToken在后端自动刷新用户.无论哪种方式,我都没有想法.

代码片段如下.我已经使用GoogleSignIn 2.2.0和2.3.2进行了测试,并遇到了同样的问题.

...
@interface MySignInClass <GIDSignInDelegate>
...
-(void) signInWithGoogle
{
    GIDSignIn *signIn = [GIDSignIn sharedInstance];
    signIn.clientID = MY_GOOGLE_CLIENT_ID;
    signIn.shouldFetchBasicProfile = YES;
    signIn.scopes = [NSArray arrayWithObjects:@"https://www.googleapis.com/auth/userinfo.profile", @"openid", nil];
    signIn.delegate = self;
    if([signIn hasAuthInKeychain]) {
        [signIn signInSilently];
    } else {
        [signIn signIn];
    }
}
...
- (void)signIn:(GIDSignIn *)signIn 
    didSignInForUser:(GIDGoogleUser *)user
           withError:(NSError *)error 
{
    if (error != nil) {
        [self handleSignInError:error]; // Handle error
    }
    else {
        NSString *idToken = user.authentication.idToken;
        NSDictionary* logins = @{@"accounts.google.com": idToken};
        self.credentialsProvider = [[AWSCognitoCredentialsProvider alloc] 
           initWithRegionType:MY_COGNITO_REGION_TYPE
                   identityId:nil
               identityPoolId:MY_COGNITO_IDENTITY_POOL
                       logins:logins];
       AWSServiceConfiguration *configuration = [[AWSServiceConfiguration alloc] 
            initWithRegion:MY_COGNITO_REGION                                                              
       credentialsProvider:self.credentialsProvider];
       AWSServiceManager.defaultServiceManager.defaultServiceConfiguration = configuration;
       // AWSTask stuff removed for simplicity
       AWSTask* task = [self.credentialsProvider getIdentityId];
       ...
    }
}
...
- (void)signIn:(GIDSignIn *)signIn
     didDisconnectWithUser:(GIDGoogleUser *)user
                 withError:(NSError *)error 
{
    [self handleGoogleSignout]; // Do signout stuff
}
...

最佳答案 像这样拨打 GIDSignIn’s signInSilently method:

[[GIDSignIn sharedInstance] signInSilently];

这将最终再次使用idToken调用您的signIn:didSignInForUser:withError:委托方法实现.

我已经确认使用2.4.0 release of Google Sign-In for iOS上面使用signInSilently的方法确实可以为你提供一个未过期的新idToken.

点赞