Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Should I store the ID token persistently in Google sign in?

I am using Google sign-in in my app, and I will send the ID token to my backhand server as soon as the user signed in and the ID token is retrieved. For now I will add the ID token to the header of each HTTP request, and I validate it, get user's ID and respond data back to my app. I am wondering if it is OK to store the ID token persistently and use it for all the future request. Will the ID token change or expire some time? If so, how to get new ID token? I can't find any approach other than asking user to sign in again. Or should I only validate the ID token for once and use ID directly in the future requests?

like image 416
Perqin Avatar asked Jul 28 '16 18:07

Perqin


1 Answers

Don't store an ID token. 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 52
Steven Avatar answered Sep 23 '22 20:09

Steven