SafetyNet reCAPTCHA API

SafetyNet 服务包含一个 reCAPTCHA API,可用于保护您的应用免受恶意流量的侵害。

reCAPTCHA 是一项免费服务,它使用先进的风险分析引擎来保护您的应用免受垃圾邮件和其他滥用行为的影响。如果服务怀疑与您的应用交互的用户可能是机器人而非人类,它会提供一个 CAPTCHA 验证码,人类必须先解决该验证码,您的应用才能继续执行。

本文档介绍如何将 SafetyNet 中的 reCAPTCHA API 集成到您的应用中。

附加服务条款

访问或使用 reCAPTCHA API 即表示您同意遵守 Google API 服务条款以及以下 reCAPTCHA 服务条款。在访问 API 之前,请阅读并理解所有适用的条款和政策。

reCAPTCHA 服务条款

您确认并理解,reCAPTCHA API 的工作原理是收集硬件和软件信息(例如设备和应用数据以及完整性检查结果),并将这些数据发送到 Google 进行分析。根据 Google API 服务条款第 3(d) 条,您同意,如果您使用 API,您有责任提供任何必要的通知或同意,以允许与 Google 收集和共享这些数据。

注册 reCAPTCHA 密钥对

要注册用于 SafetyNet reCAPTCHA API 的密钥对,请访问 reCAPTCHA Android 注册网站,然后完成以下步骤序列

  1. 在出现的表单中,提供以下信息

    • 标签: 您的密钥的唯一标签。通常,您使用公司或组织的名称。
    • reCAPTCHA 类型: 选择 reCAPTCHA v2,然后选择 reCAPTCHA Android
    • 包名: 提供每个使用此 API 密钥的应用的包名。应用要使用此 API,您输入的包名必须与应用的包名完全匹配。每行输入一个包名。
    • 所有者: 为组织中监控应用 reCAPTCHA 评估的每个个人添加电子邮件地址。
  2. 选择接受 reCAPTCHA 服务条款复选框。

  3. 向所有者发送提醒: 如果您想接收有关 reCAPTCHA API 的电子邮件,请选中此复选框,然后点击提交

  4. 在下一页上,您的公共密钥和私有密钥分别显示在网站密钥密钥下方。您在发送验证请求时使用网站密钥,在验证用户响应令牌时使用密钥。

添加 SafetyNet API 依赖项

在使用 reCAPTCHA API 之前,将 SafetyNet API 添加到您的项目中。如果您使用 Android Studio,请将此依赖项添加到您的应用级 Gradle 文件中。有关更多信息,请参阅 SafetyNet API 设置

使用 reCAPTCHA API

本部分介绍如何调用 reCAPTCHA API 发送 CAPTCHA 验证请求并接收用户响应令牌。

发送验证请求

要调用 SafetyNet reCAPTCHA API,请调用 verifyWithRecaptcha() 方法。通常,此方法对应于用户在您的 Activity 中选择一个 UI 元素(例如按钮)。

在您的应用中使用 verifyWithRecaptcha() 方法时,您必须执行以下操作

  • 将您的 API 网站密钥作为参数传入。
  • 重写 onSuccess()onFailure() 方法,以处理验证请求任务的两种可能结果。特别地,如果 API 在 onFailure() 中传入 ApiException 实例,您需要处理可以使用 getStatusCode() 检索的每个可能的status code。

以下代码片段显示了如何调用此方法

Kotlin

fun onClick(view: View) {
    SafetyNet.getClient(this).verifyWithRecaptcha(YOUR_API_SITE_KEY)
            .addOnSuccessListener(this as Executor, OnSuccessListener { response ->
                // Indicates communication with reCAPTCHA service was
                // successful.
                val userResponseToken = response.tokenResult
                if (response.tokenResult?.isNotEmpty() == true) {
                    // Validate the user response token using the
                    // reCAPTCHA siteverify API.
                }
            })
            .addOnFailureListener(this as Executor, OnFailureListener { e ->
                if (e is ApiException) {
                    // An error occurred when communicating with the
                    // reCAPTCHA service. Refer to the status code to
                    // handle the error appropriately.
                    Log.d(TAG, "Error: ${CommonStatusCodes.getStatusCodeString(e.statusCode)}")
                } else {
                    // A different, unknown type of error occurred.
                    Log.d(TAG, "Error: ${e.message}")
                }
            })
}

Java

public void onClick(View v) {
    SafetyNet.getClient(this).verifyWithRecaptcha(YOUR_API_SITE_KEY)
        .addOnSuccessListener((Executor) this,
            new OnSuccessListener<SafetyNetApi.RecaptchaTokenResponse>() {
                @Override
                public void onSuccess(SafetyNetApi.RecaptchaTokenResponse response) {
                    // Indicates communication with reCAPTCHA service was
                    // successful.
                    String userResponseToken = response.getTokenResult();
                    if (!userResponseToken.isEmpty()) {
                        // Validate the user response token using the
                        // reCAPTCHA siteverify API.
                    }
                }
        })
        .addOnFailureListener((Executor) this, new OnFailureListener() {
                @Override
                public void onFailure(@NonNull Exception e) {
                    if (e instanceof ApiException) {
                        // An error occurred when communicating with the
                        // reCAPTCHA service. Refer to the status code to
                        // handle the error appropriately.
                        ApiException apiException = (ApiException) e;
                        int statusCode = apiException.getStatusCode();
                        Log.d(TAG, "Error: " + CommonStatusCodes
                                .getStatusCodeString(statusCode));
                    } else {
                        // A different, unknown type of error occurred.
                        Log.d(TAG, "Error: " + e.getMessage());
                    }
                }
        });
}

验证用户响应令牌

当 reCAPTCHA API 执行 onSuccess() 方法时,表示用户已成功完成 CAPTCHA 挑战。但是,此方法仅表明用户正确解决了 CAPTCHA。您仍然需要从您的后端服务器验证用户的响应令牌。

要了解如何验证用户的响应令牌,请参阅 验证用户的响应