The SafetyNet service includes a reCAPTCHA API that you can use to protect your app from malicious traffic.
reCAPTCHA is a free service that uses an advanced risk analysis engine to protect your app from spam and other abusive actions. If the service suspects that the user interacting with your app might be a bot instead of a human, it serves a CAPTCHA that a human must solve before your app can continue executing.
This document explains how to integrate the reCAPTCHA API from SafetyNet into your app.
Additional Terms of Service
By accessing or using the reCAPTCHA API, you agree to the Google APIs Terms of Service, and to these Additional Terms. Please read and understand all applicable terms and policies before accessing the APIs.
reCAPTCHA Terms of Service
You acknowledge and understand that the reCAPTCHA API works by collecting hardware and software information, such as device and application data and the results of integrity checks, and sending that data to Google for analysis. Pursuant to Section 3(d) of the Google APIs Terms of Service, you agree that if you use the APIs that it is your responsibility to provide any necessary notices or consents for the collection and sharing of this data with Google.Registering a reCAPTCHA key pair
To register a key pair for SafetyNet reCAPTCHA API, navigate to the reCAPTCHA Android signup site, then complete the following sequence of steps:
-
In the form that appears, provide the following information:
- Label: A unique label for your key. Typically, you use the name of your company or organization.
- Package Names: Provide the package name of each app that uses this API key. In order for an app to use the API, the package name that you enter must be an exact match of the package name for that app. Enter each package name on its own line.
- Send alerts to owners: Check this checkbox if you want to receive emails about the reCAPTCHA API.
-
Check the Accept the reCAPTCHA Terms of Service checkbox, then click Register.
- In the Adding reCAPTCHA to your app section on the page that appears next, your public and private keys appear under Site key and Secret key, respectively. You use the site key when you send the verify request, and you use the secret key when you validate the user response token.
Setting up Google Play services
Before connecting to Google Play services, you need to set up your project with the Google Play services SDK. If you use Android Studio and you want to selectively compile Google Play services APIs into your Gradle dependencies, you should include the build rules shown in the following code snippet:
apply plugin: 'com.android.application'
...
dependencies {
compile 'com.google.android.gms:play-services-base:11.0.2'
compile 'com.google.android.gms:play-services-basement:11.0.2'
compile 'com.google.android.gms:play-services-safetynet:11.0.2'
compile 'com.google.android.gms:play-services-tasks:11.0.2'
}
For more information, see Set Up Google Play services.
Connecting to Google Play services
The SafetyNet API is part of Google Play services. To connect to the API, you
need to create an instance of the
GoogleApiClient
class. After you have established a connection to Google Play services, you can
use the Google API client classes to connect to the SafetyNet API. For more
details about using the client in your app, see Accessing Google
APIs.
In your activity's onCreate() method,
create an instance of the Google API client using
GoogleApiClient.Builder.
As you're creating the client, add the SafetyNet API, as shown in the following
code example:
private GoogleApiClient mGoogleApiClient;
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(SafetyNet.API)
.addConnectionCallbacks(myMainActivity.this)
.addOnConnectionFailedListener(myMainActivity.this)
.build();
mGoogleApiClient.connect();
In addition, you should implement the
onConnectionFailed()
callback method. This method is executed when the connection fails, either
because the Google Play services APK is missing or because the APK isn't
up-to-date. The callback receives an error code defined in
ConnectionResult.
Your app can use these error codes to handle the failure appropriately.
Using the reCAPTCHA API
This section describes how to call the reCAPTCHA API to send a CAPTCHA verification request and receive the user response token.
Send the verify request
After creating an instance of
GoogleApiClient,
you can pass in this client instance and your API site key (public key) as
parameters into the verifyWithRecaptcha() method. This method determines
whether a user has completed the CAPTCHA successfully. You must override the
onResult()
method to handle each possible result status from this API call. For more
information, see Handling communication errors.
Usually, the verifyWithRecaptcha() method corresponds to the user's selecting
a UI element in your activity. The following code snippet shows how to invoke
this method:
// This method is called when the user interacts with the element in your
// app's UI that invokes the CAPTCHA UI.
public void onClick(View v) {
SafetyNet.SafetyNetApi.verifyWithRecaptcha(mGoogleApiClient, mSiteKey)
.setResultCallback(new ResultCallback<SafetyNetApi.RecaptchaTokenResult>() {
@Override
public void onResult(SafetyNetApi.RecaptchaTokenResult result) {
Status status = result.getStatus();
if ((status != null) && status.isSuccess()) {
// Indicates communication with reCAPTCHA service was
// successful. Use result.getTokenResult() to get the
// user response token if the user has completed
// the CAPTCHA.
if (!result.getTokenResult().isEmpty()) {
// User response token must be validated using the
// reCAPTCHA site verify API.
}
} else {
Log.e("MY_APP_TAG", "Error occurred " +
"when communicating with the reCAPTCHA service.");
// Use status.getStatusCode() to determine the exact
// error code. Use this code in conjunction with the
// information in the "Handling communication errors"
// section of this document to take appropriate action
// in your app.
}
}
});
}
The following section describes how to validate the user response token.
Validate the user response token
Although the value of
isSuccess()
may indicate that the user has completed the CAPTCHA challenge, it only means
that the user has solved the CAPTCHA correctly. Your app still needs to validate
the user's response token.
To learn how to validate the user's response token, see Verifying the user's response.
Handling communication errors
If your app cannot communicate with the reCAPTCHA service successfully, it may be because the API is encountering an error. You should add logic in your app to gracefully handle such an error. Also, when the error occurs, your app should display a message to your users explaining why your app cannot finish processing their CAPTCHA response.
The following list shows the status codes for the most common API errors:
RECAPTCHA_INVALID_SITEKEY-
The site key is invalid. Check that you've registered an API key successfully and that you've correctly copied the site key as a parameter when calling the API.
Constant value: 12007
RECAPTCHA_INVALID_KEYTYPE-
The type of site key is invalid. Create a new site key by navigating to the reCAPTCHA Android signup site.
Constant value: 12008
RECAPTCHA_INVALID_PACKAGE_NAME-
The calling app's package name doesn't match any of the names that you've associated with the site key. Add the calling app's package name to the site key on the reCAPTCHA Admin Console, or disable package name validation for your site key.
Constant value: 12013
UNSUPPORTED_SDK_VERSION-
The API isn't supported on the device's Android SDK version. Upgrade to a new version of the Android SDK, then try communicating with the API again.
Constant value: 12006
TIMEOUT-
The session timed out as the API waited for a response, either because the user didn't interact with the CAPTCHA or because the CAPTCHA loading process itself timed out. Wait for the user to invoke the API again. In the meantime, you can inform the user that they must complete the CAPTCHA to continue using your app.
Constant value: 15
NETWORK_ERROR-
There is no Internet connection. After ensuring connectivity, try communicating with the API again.
Constant value: 7
ERROR-
The operation encountered a general failure.
Constant value: 13
For more details about the status codes that the reCAPTCHA API can return, see
the SafetyNetStatusCodes
reference.