According to https://developers.google.com/android/reference/com/google/android/gms/auth/api/signin/GoogleSignInApi.html#constant-summary
If you use the ID token expiry time to determine your session lifetime, you should retrieve a refreshed ID token, by calling silentSignIn prior to each API call to your application server.
I am trying to get a new token by calling silentSignIn. But, I always get the same expired ID token. Can some one please help me in pointing out the right documentation that shows how to force refresh to get a new token. My code is nothing special. It's almost the same as what we have in google's sample.
private void buildGoogleApiClient()
{
// Configure sign-in to request the user's ID, email address, and basic profile. ID and
// basic profile are included in DEFAULT_SIGN_IN.
GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
//.requestServerAuthCode(serverClientId)
.requestIdToken(SERVER_ID)
.requestScopes(new Scope(Scopes.PLUS_LOGIN))
.requestEmail()
.build();
// Build a GoogleApiClient with access to GoogleSignIn.API and the options above.
mGoogleApiClient = new GoogleApiClient.Builder(this)
.enableAutoManage(this, this)
.addApi(Auth.GOOGLE_SIGN_IN_API, gso)
.build();
}
I build my API as above and when user clicks on login with google button I perform the following action
OptionalPendingResult<GoogleSignInResult> opr = Auth.GoogleSignInApi.silentSignIn(mGoogleApiClient);
if (opr.isDone())
{
// If the user's cached credentials are valid, the OptionalPendingResult will be "done"
// and the GoogleSignInResult will be available instantly.
Timber.d("Got cached sign-in");
GoogleSignInResult result = opr.get();
handleSignInResult(result);
}
else
{
// If the user has not previously signed in on this device or the sign-in has expired,
// this asynchronous branch will attempt to sign in the user silently. Cross-device
// single sign-on will occur in this branch.
Timber.d("Checking if user has already given access to this app on an other device.");
showProgressDialog();
opr.setResultCallback(new ResultCallback<GoogleSignInResult>()
{
@Override
public void onResult(GoogleSignInResult googleSignInResult)
{
hideProgressDialog();
handleSignInResult(googleSignInResult);
}
});
}
handleSignInResult method would get the id token as
GoogleSignInAccount acct = result.getSignInAccount();
String idToken = acct.getIdToken();
Timber.d(acct.getIdToken());
EDIT 1
I have another related question.
After I revoked the permission from https://security.google.com/settings/u/1/security/permissions I was still able to retrieve the ID token(JWT). Let's assume that this token is cached and Android play services is providing it from a local copy. After the token expires(60 mins) play service should contact Google's service to get the latest status. But, I don't see this happening. In fact, another strange thing that I have noticed is when I call silentSignIn() after like a day or so, I get a new token with out user's consent. Can some one please test this use case and let me know the output.
How can I make sure user's are requested to give permission again when they have revoked it.
You will need to use startActivityForResult()
, then handle the sign-in result in onActivityResult()
, as explained here Integrating Google Sign-In into Your Android App. Then, to verify the authenticity of the token, please see Google's guide for Google Sign-In for Android on how to Authenticate with a backend server.
A simple way is to pass the token to the Google tokeninfo endpoint
https://www.googleapis.com/oauth2/v3/tokeninfo?id_token=XYZ123
where XYZ123 is your token.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With