¿Cómo actualizar authentication.idToken con GIDSignIn o GIDAuthentication?

5

ACTUALIZACIÓN 2015-10-28: la versión 2.4.0 de Google Sign-In para iOS parece haber resuelto este problema, y ​​tanto el idToken como el accessToken se actualizan según sea necesario mediante los nuevos GIDAuthenticationmétodos getTokensWithHandler:y refreshTokensWithHandler:. GIDSignInEl método SignInSilentlytambién actualiza ambos tokens.


Estoy usando AWS Mobile SDK para iOS y he implementado el inicio de sesión de Google como proveedor de credenciales de Cognito utilizando el código de muestra de AWS Cognito Sync como base. El flujo de inicio de sesión (y el subsiguiente inicio de sesión silencioso) funciona correctamente y los usuarios que inician sesión pueden acceder a los recursos de AWS como DynamoDB según lo previsto.

Mi problema es que user.authentication.idTokencaduca después de una hora y en ese momento las llamadas a los servicios de AWS fallan con errores de autenticación. Puedo actualizar el user.authentication.accessTokenuso

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

pero esto no actualiza el idToken. También he intentado llamar

[[GoogleSignIn sharedInstance] signInSilently];

lo que me da un idToken válido la primera vez que se llama en la sesión, pero aunque se completa correctamente, no actualiza el idToken en llamadas posteriores dentro de la misma sesión.

He estado verificando / volcando el contenido del token usando

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

y

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

No estoy seguro de si el problema es que GIDSignIn no está actualizando idToken, o que AWS debería usar el refreshToken de alguna manera para actualizar automáticamente al usuario en el backend. De cualquier manera me quedo sin ideas.

Fragmentos de código a continuación. Probé con GoogleSignIn 2.2.0 y 2.3.2 y experimenté el mismo problema.

...
@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
}
...
2
  • Enlace a la discusión en los foros de AWS en caso de que haya algún progreso desde ese lado. 27/10/15 a las 14:10
  • 1
    Acabo de actualizar a Google Sign-In para iOS 2.4.0 y parece que se ha solucionado. Tanto el idToken como el accessToken ahora se actualizan si han expirado y la autenticación sigue siendo válida. Aquí están las notas de la versión . Actualizaré la publicación principal. 30 oct 2015 a las 16:28
2

Llame al método signInSilently de GIDSignIn así:

[[GIDSignIn sharedInstance] signInSilently];

Esto terminará llamando a la signIn:didSignInForUser:withError:implementación de su método delegado con el idToken nuevamente.

He verificado que con la versión 2.4.0 de Google Sign-In para iOS, el enfoque anterior de usar signInSilently realmente funciona para darle un nuevo idToken que no ha expirado.

3
  • Recibo el token en la devolución de llamada cuando lo probé. Supongo que estás diciendo que cuando caduca, envía el mismo token caducado. Veré si puedo encontrar la paciencia para esperar hoy y jugar con eso. Tengo otra idea si esto no funciona ... 27/10/15 a las 16:09
  • Me refiero al idToken, no al token de acceso. Los métodos signIn guardan el token en el llavero, por lo que signInSilently debería hacer lo mismo, pero llamar a [[GIDSignIn sharedInstance] signInSilently] .currentUser.authentication.idToken devuelve el mismo valor. 27/10/15 a las 19:48
  • Sí, lo entendí y en mi prueba rápida, el IDToken se devuelve al delegado, pero después de esperar una hora, vi que continúa devolviendo el token antiguo, ahora vencido. Creo que la única forma de hacer que esto suceda es volver a acceder al Token Endpoint de Google, pero no está claro cómo hacerlo mientras se usa GIDSignIn, ya que GIDSignIn no parece exponer el código de autenticación original. 28/10/15 a las 19:08
0

También tuve este problema. Intenté todo lo posible, ese token simplemente no está siendo renovado por G + iOS SDK.

La solución de nuestro lado fue enviar refresh_token a nuestro servidor, y pudieron renovar correctamente el token de su lado, accediendo a una API de Google y luego enviando el nuevo token a mi aplicación. Desafortunadamente, no tengo acceso ahora allí, para decirles exactamente qué API, solo mañana.

2
  • Gracias Beny. Desafortunadamente, en mi caso, el backend es Amazon Cognito, por lo que tampoco tengo ningún control sobre eso. 22/10/15 a las 13:08
  • Realmente espero que encuentre la solución correcta para esto. Háganos saber si tiene éxito. 22/10/15 a las 13:40
0

¿Qué tal usar un temporizador a los 30 minutos y luego llamar al signInSilently?

2
  • Fue un error que se ha corregido. 20 de marzo de 2016 a las 1:07
  • Me acabo de enterar. Gracias por responder y perdón por la publicación desactualizada. 20 de marzo de 2016 a las 1:43