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 注册网站,然后完成以下步骤序列
在出现的表单中,提供以下信息
- 标签:密钥的唯一标签。通常,您使用公司或组织的名称。
- reCAPTCHA 类型:选择reCAPTCHA v2,然后选择reCAPTCHA Android。
- 软件包: 提供每个使用此 API 密钥的应用的软件包名称。为了让应用使用此 API,您输入的软件包名称必须与应用的软件包名称完全匹配。请在每一行输入一个软件包名称。
- 所有者: 添加您组织中监控应用 reCAPTCHA 评估的每个人的电子邮件地址。
选择接受 reCAPTCHA 服务条款复选框。
向所有者发送警报:如果您想接收有关 reCAPTCHA API 的电子邮件,请选择此复选框,然后单击提交。
在接下来出现的页面上,您的公钥和私钥分别显示在站点密钥和密钥下。当您发送验证请求时,您将使用站点密钥;当您验证用户响应令牌时,您将使用密钥。
添加 SafetyNet API 依赖项
在使用 reCAPTCHA API 之前,请将 SafetyNet API 添加到您的项目中。如果您使用的是 Android Studio,请将此依赖项添加到您的应用级 Gradle 文件中。更多信息,请参见SafetyNet API 设置。
使用 reCAPTCHA API
本节介绍如何调用 reCAPTCHA API 发送 CAPTCHA 验证请求并接收用户响应令牌。
发送验证请求
要调用 SafetyNet reCAPTCHA API,您可以调用verifyWithRecaptcha()
方法。通常,此方法对应于用户在您的活动中选择 UI 元素(例如按钮)。
在您的应用中使用verifyWithRecaptcha()
方法时,您必须执行以下操作
- 将您的 API 站点密钥作为参数传入。
- 覆盖
onSuccess()
和onFailure()
方法以处理验证请求任务的两种可能结果。特别是,如果 API 将ApiException
的实例传递到onFailure()
,则需要处理您可以使用getStatusCode()
检索的每个可能的状态代码。
以下代码片段显示了如何调用此方法
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。您仍然需要从后端服务器验证用户的响应令牌。
要了解如何验证用户的响应令牌,请参见验证用户的响应。