We're currently able to authenticate requests between our Android client and server using a deprecated approach:
String scope = "audience:server:client_id:" + SERVER_CLIENT_ID;
String account = getAnyGoogleAccountFromDevice();
String idToken = GoogleAuthUtil.getToken(context, account, scope);
On the server side we validate the idToken
using Google's certificates and verify the audience is our client.
This works well, but it seems Google has deprecated this approach and wants developers to switch to the new Sign-in APIs from PlayServices 8.3+:
https://android-developers.googleblog.com/2015/11/improvements-to-sign-in-with-google.html
https://developers.googleblog.com/2016/11/moving-to-google-sign-in-for-a-better-user-experience-and-higher-conversion-rates.html
But the new docs approach, explained here and here, doesn't allow use of some Google account we give it, but instead requires the user to sign-in to the app. We want to have a transparent way of authenticating with the backend, without any user intervention or UI, we don't need the user's name/email/profile information, just require some token to validate the requests are coming from our own client.
Is there a way to do that using the new Google Sign-in APIs?
If you already know the user's email address you can refresh the ID token with the following:
// Run on a non-UI thread
GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.setAccountName(emailAddress)
.requestIdToken(SERVER_CLIENT_ID)
.build();
GoogleApiClient client = new Builder(context)
.addApi(Auth.GOOGLE_SIGN_IN_API, gso)
.build();
ConnectionResult conn = client.blockingConnect();
if (!conn.isSuccess()) {
Log.e(TAG, "Couldn't connect GoogleApiClient");
return;
}
GoogleSignInResult result = Auth.GoogleSignInApi.silentSignIn(client).await();
GoogleSignInAccount acct = result.getSignInAccount();
Log.d(TAG, "ID Token: " + acct.getIdToken());
client.disconnect();