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?
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
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