Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to refresh ID token after it expires when integrating Google sign-in on Android?

I've followed the guides on https://developers.google.com/ and I can get the Google ID token of the signed in user after the user signed in. But I noticed that the token will expire in 1 hour. I cannot find any official reference that tells me how to deal with expired Google ID token, so I can only ask the user to click the Google sign-in button again.

How can I refresh a valid Google ID token after the old one expires, without bothering user to manually sign in again and again?

like image 247
Perqin Avatar asked Aug 03 '16 07:08

Perqin


People also ask

How do I refresh Google ID token?

You can refresh an Identity Platform ID token by issuing an HTTP POST request to the securetoken.googleapis.com endpoint. The refresh token's grant type, always "refresh_token".

How do I refresh an expired access token?

To refresh your access token as well as an ID token, you send a token request with a grant_type of refresh_token . Be sure to include the openid scope when you want to refresh the ID token. If the refresh token is valid, then you get back a new access and the refresh token.

Can I refresh ID token?

You can refresh access and ID tokens using the /token endpoint with the grant_type set to refresh_token . Before calling this endpoint, obtain the refresh token from the SDK and ensure that you have included offline_access as a scope in the SDK configurations.

Do refresh tokens expire Google?

When does a refresh token expire ? Refresh tokens do not expire, unless there are few special conditions : The user has removed your Google application. The refresh token has not been used for six months.


1 Answers

Yes, Google ID tokens are issued for one hour validity and will expire, you can simply use silentSignIn in your app to get a new one without any user interaction. If your existing token hasn't expired yet, you will get the (cached) version back (OptionalPendingResult returned will have isDone() == true); if it expired already, you will get a refreshed one (but it will take a little longer and thus OptionalPendingResult isDone() will be false).

Here is sample code (UI thread, see note below about a worker thread):

    GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
            .requestIdToken(getString(R.string.server_client_id))

    mGoogleApiClient = new GoogleApiClient.Builder(this)
            .enableAutoManage(this /* FragmentActivity */, this /* OnConnectionFailedListener */)
            .addApi(Auth.GOOGLE_SIGN_IN_API, gso)
            .build();
...

    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.
        Log.d(TAG, "Got cached sign-in");
        GoogleSignInResult result = opr.get();
        handleSignInResult(result);  // result.getSignInAccount().getIdToken(), etc.
    } 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.
        opr.setResultCallback(new ResultCallback<GoogleSignInResult>() {
            @Override
            public void onResult(GoogleSignInResult googleSignInResult) {
                handleSignInResult(googleSignInResult);  // result.getSignInAccount().getIdToken(), etc.
            }
        });
    }

Keep in mind whether you call silentSignIn on a UI thread or worker thread. If you call it on worker thread, take a look at this post with blockingConnect() + await() which simplifies the code a lot: Silent sign in to retrieve token with GoogleApiClient

like image 150
Steven Avatar answered Oct 09 '22 23:10

Steven