This page explains how to integrate with the account verification feature.
Account verification is a feature that allows you to verify that your users own the email address or phone number that is associated with their account. It can help protect your users against credential stuffing attacks. This feature allows you to send a verification code by email and SMS and provides an input screen to validate the user's response. You can retrieve the verification results on the risk assessment.
The integration of the account verification feature is done in a few steps:
- Instrument the critical flow (login, signup, etc.) on the client, before requesting the assessment.
- Request and interpret the account verification information in the assessment.
- Trigger an account verification challenge on the client.
- Request a new assessment to make sure that the user's email address or phone number was successfully verified.
Before you begin
Make sure to complete the steps in the Quickstart to gain access to the API. Depending on the platforms for which you want to enable account verification, you will also need to follow the client-specific integration guides:
Instrumenting the critical flow on the client
This section explains how to pass the necessary information to reCAPTCHA Enterprise for use in the risk assessment.
On Android
Add the username to the RecaptchaAction
which will be used in execute
calls.
This can be done as follows:
Bundle bundle = new Bundle();
bundle.putString("username", "foo@bar.com");
RecaptchaAction action =
new RecaptchaAction(
new RecaptchaActionType(RecaptchaActionType.LOGIN), bundle));
On iOS
You will need to provide the username
argument.
For example:
recaptchaClient.execute(
RecaptchaAction(
action: .login,
extraParameters: ["username": "foo@bar.com"])
).then { token in
// Do something with the token
}.catch { error in
// Act on the error.
}
On Web
You will need to append an additional username
parameter to your execute
call, for example:
grecaptcha.enterprise.execute({
action: 'login',
username: 'foo@bar.com'
}).then(token => {
/// Handle the generated token.
});
Note that execute
returns a promise that is resolved upon token generation.
Requesting an assessment
Regardless of the platform that created the token, you can follow the instructions to create an assessment using that token.
You must supply the username and the endpoint to verify in the Assessment
. You
can provide multiple endpoints, for example an email address and a phone number:
{
"event": {
"token": "token",
"siteKey": "key"
},
"accountVerification": {
"username": "foo@bar.com",
"endpoints: [{
"emailAddress": "foo@bar.com",
},
{
"phoneNumber": "+11111111111",
}]
}
}
If the integration with the feature is successful, the assessment should contain more information related to account verification specifically. For example:
{
[...],
"accountVerification": {
"username": "foo@bar.com",
"endpoints: [{
"emailAddress": "foo@bar.com",
"requestToken": "tplIUFvvJUIpLaOH0hIVj2H71t5Z9mDK2RhB1SAGSIUOgOIsBv",
"lastVerificationTime": "",
},
{
"phoneNumber": "+11111111111",
"requestToken": "fwdgk0kcg1W0mbpetYlgTZKyrp4IHKzjgRkb6vLNZeBQhWdR3a",
"lastVerificationTime": "",
}],
"latestVerificationResult": "RESULT_UNSPECIFIED"
}
}
The assessment will contain the date and time of the latest successful
verification for the given endpoints on the device that issued the token, if
any. It will also contain one requestToken
field per endpoint, which contains
an opaque blob that you will need to send back to the client, if you decide to
trigger an account verification challenge for that endpoint. The request tokens
are valid for 15 minutes.
Triggering an account verification challenge on the client
If you have have decided to challenge the user based on the information contained in the assessment, then you must send the account verification request token for the endpoint you want to verify from the assessment back to the client. This request token will be needed to trigger the account verification challenge.
On Android
The account verification challenge is sent with a call to challengeAccount
from an Context
in your app.
Recaptcha.getClient(this)
.challengeAccount(recaptchaHandle, requestToken)
.addOnSuccessListener(
this,
new OnSuccessListener<VerificationHandle>() {
@Override
public void onSuccess(VerificationHandle handle) {
VerificationHandle verificationHandle = handle;
// Handle success ...
}
})
.addOnFailureListener(
this,
new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
if (e instanceof ApiException) {
ApiException apiException = (ApiException) e;
Status apiErrorStatus = apiException.getStatusCode();
// Handle api errors ...
} else {
// Handle other failures ...
}
}
});
Once you obtain the PIN from the user, you must call verifyAccount
from an
Activity
in your app to verify that the entered PIN was correct.
Recaptcha.getClient(this)
.verifyAccount("userProvidedPIN", recaptchaHandle)
.addOnSuccessListener(
this,
new OnSuccessListener<VerificationResult>() {
@Override
public void onSuccess(VerificationResult result) {
if (result.getVerificationStatus().isSuccess()) {
String recaptchaToken = result.recaptchaToken().orNull()
// Handle success ...
} else {
VerificationHandle verificationHandle =
result.verificationHandle().orNull();
Status errorStatus = result.getVerificationStatus();
// Handle retries ...
}
}
})
.addOnFailureListener(
this,
new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
if (e instanceof ApiException) {
ApiException apiException = (ApiException) e;
Status apiErrorStatus = apiException.getStatusCode();
// Handle api errors ...
} else {
// Handle other failures ...
}
}
});
On iOS
The challenge is triggered with a call to challengeAccount
.
recaptchaClient.challengeAccount(withRequestToken: "Request Token").then { verificationHandler in
// Show your UI and retrieve the pin from the user.
}.catch { error in
// Handle error.
}
Then once you get the PIN from the user you can use the verifyPin
of the
verificationHandler
to finish the verification.
handler.verifyPin("pin") { recaptchaToken, recaptchaError in
// Handle token/error.
}
On Web
The challenge is triggered with a single function call:
grecaptcha.enterprise.challengeAccount({
'account-token': requestTokenFromCreateAssessment,
'container': containerHTMLComponentID
}).then(newToken => {
// Handle the new token.
});
where containerHTMLComponentID
is the ID of an HTML component in which the
verification challenge should be rendered. If you do not specify this parameter,
then the challenge will be rendered in an overlay on top of the page.
The challengeAccount
function returns a promise that is resolved once the
challenge is completed, or rejected in case of error or timeout. Upon
completion, the resolver is given a new generated token that contains updated
information to be retrieved by requesting a new assessment.
Requesting a new assessment
You must request a new Assessment
, once again including the username
and
endpoints
fields.
Once the flow has been completed on the client, you should have received a new token that you can use to get the verdict of the verification you triggered. The assessment should contain a very recent timestamp regarding the latest successful verification, along with a success result status. For example, if you decided to verify an email endpoint:
{
[...],
"accountVerification": {
"username": "foo@bar.com",
"endpoints: [{
"emailAddress": "foo@bar.com",
"requestToken": "tplIUFvvJUIpLaOH0hIVj2H71t5Z9mDK2RhB1SAGSIUOgOIsBv",
"lastVerificationTime": "2020-03-23 08:27:12 PST",
}],
"latestVerificationResult": "SUCCESS_USER_VERIFIED"
}
}
The field latestVerificationResult
can also show a different status,
including:
ERROR_USER_NOT_VERIFIED
if the user failed the verification challengeERROR_SITE_ONBOARDING_INCOMPLETE
if your site is not properly onboarded to the featureERROR_CRITICAL_INTERNAL
if the verification could not be completed due to an internal error in our systems.