After you have successfully retrieved a user's credentials or retrieved sign-in hints, you can check if an ID token is available for the credential. An ID token is a signed assertion of a user's identity that also contains a user's basic profile information, possibly including an email address that has been verified by Google. When ID tokens are available, you can use them to securely authenticate with your app's backend, or to skip the email verification step when creating a new account.
An ID token is available when a Credential
object's user ID matches the user
ID of a Google account that is signed in on the device.
To sign in with an ID token, first retrieve the ID token with the getIdTokens
method. Then, send the ID token to your app's backend. On the backend, verify
the token using either a Google API client library or a general-purpose JWT
library.
Before you begin
- Your app must be able to successfully retrieve a user's credentials or retrieve a sign-in hint.
- You must call
setAccountTypes(IdentityProviders.GOOGLE)
when you build theCredentialRequest
andHintRequest
objects.
Get an ID token from the Credentials object
After you retrieve a user's credentials, check if the Credentials
object
includes an ID token. If it does, call getIdTokens
to retrieve it, and send it
to your backend by HTTPS POST.
if (!credential.getIdTokens().isEmpty()) {
String idToken = credential.getIdTokens().get(0).getIdToken();
HttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost("https://yourbackend.example.com/tokensignin");
try {
List nameValuePairs = new ArrayList(1);
nameValuePairs.add(new BasicNameValuePair("idToken", idToken));
httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
HttpResponse response = httpClient.execute(httpPost);
int statusCode = response.getStatusLine().getStatusCode();
final String responseBody = EntityUtils.toString(response.getEntity());
Log.i(TAG, "Signed in as: " + responseBody);
}
}
Verify the ID token on the backend
After you receive the ID token by HTTPS POST, you must verify the token's
signature, and verify the token's aud
, iss
, and exp
claims.
The aud
claim of an ID token from Smart Lock for Passwords has the following
format:
android://SHA512_HASH@ANDROID_PACKAGE_NAME
The value SHA512HASH is the SHA-512 hash of your signing
certificate. You can get this value using the keytool
and openssl
utilities:
keytool -exportcert -keystore path-to-keystore -alias key-name
| openssl sha -sha512 -binary
| base64 -w 0
| tr '+/' '-'
Or, you can get the SHA-512 hash by examining an ID token you know to be valid.
JWT libraries can handle some of these verification tasks for you. For example, using the Google API client library for Java:
import com.google.api.client.googleapis.auth.oauth2.GoogleIdToken;
import com.google.api.client.googleapis.auth.oauth2.GoogleIdToken.Payload;
import com.google.api.client.googleapis.auth.oauth2.GoogleIdTokenVerifier;
...
// Verifier that checks that the token has the proper issuer and audience,
// and hasn't expired
private static GoogleIdTokenVerifier verifier =
new GoogleIdTokenVerifier.Builder(transport, jsonFactory)
.setAudience(Arrays.asList(String.format("android://%s@%s", SHA512_HASH, PACKAGE_NAME)))
.build();
// (Receive idTokenString by HTTPS POST)
GoogleIdToken idToken = verifier.verify(idTokenString);
if (idToken != null) {
Payload payload = idToken.getPayload();
System.out.println("User email: " + payload.getEmail());
if (payload.getEmailVerified()) {
System.out.println("Email verified by Google.");
}
} else {
System.out.println("Invalid ID token.");
}
See the Google Sign-In documentation for more details.