Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to refresh authentication.idToken with GIDSignIn or GIDAuthentication?

UPDATE 2015-10-28 - Release 2.4.0 of Google Sign-In for iOS appears to have resolved this problem, with both the idToken and the accessToken being refreshed as necessary by the new GIDAuthentication methods getTokensWithHandler: and refreshTokensWithHandler:. GIDSignIn method SignInSilently also refreshes both tokens.


I'm using AWS Mobile SDK for iOS, and I've implemented Google sign-in as a Cognito credentials provider using the AWS Cognito Sync sample code as a basis. The sign-in (and subsequent silent sign-in) flow is working correctly and signed-in users can access AWS resources like DynamoDB as intended.

My problem is that the user.authentication.idToken expires after one hour and at that point calls to AWS services fail with authentication errors. I can refresh the user.authentication.accessToken using

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

but this doesn't update the idToken. I've also tried calling

[[GoogleSignIn sharedInstance] signInSilently];

which gives me a valid idToken the first time it is called in the session, but although it completes successfully it doesn't refresh the idToken on subsequent calls within the same session.

I've been checking/dumping the token contents using

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

and

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

I'm not sure whether the problem is that GIDSignIn is not updating idToken, or that AWS should be using the refreshToken somehow to auto-refresh the user at the backend. Either way I'm out of ideas.

Code snippets below. I've tested using GoogleSignIn 2.2.0 and 2.3.2 and experienced the same problem.

...
@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
}
...
like image 651
Chris Pointon Avatar asked Oct 31 '22 17:10

Chris Pointon


1 Answers

Call the GIDSignIn's signInSilently method like so:

[[GIDSignIn sharedInstance] signInSilently];

This will end up calling your signIn:didSignInForUser:withError: delegate method implementation with the idToken again.

I have verified that with the 2.4.0 release of Google Sign-In for iOS the above approach of using signInSilently does indeed work for giving you a new idToken that isn't expired.

like image 57
Scott Willeke Avatar answered Nov 12 '22 14:11

Scott Willeke