将 reCAPTCHA 与 Android 应用集成

本页介绍了如何在 Android 应用中集成 reCAPTCHA。

如果您想针对可疑流量提供视觉验证,可以使用 SafetyNet reCAPTCHA API

该 SDK 使用反射和动态代码,允许修改和优化现有已部署应用/SDK 中的检测系统。系统中可用的一组类仅限于受控列表,以避免干扰应用。

准备工作

  1. 为 reCAPTCHA 准备环境

  2. 为 Android 应用平台创建 reCAPTCHA 密钥

    或者,通过执行以下步骤之一,复制现有 Android 版 reCAPTCHA 密钥的 ID:

    • 如需从 Google Cloud 控制台复制现有密钥的 ID,请执行以下操作:

      1. 前往 reCAPTCHA 页面。

        前往 reCAPTCHA

      2. 在 reCAPTCHA 密钥列表中,将鼠标指针悬停在要复制的密钥上,然后点击
    • 如需使用 REST API 复制现有密钥的 ID,请使用 projects.keys.list 方法。
    • 如需使用 gcloud CLI 复制现有密钥的 ID,请使用 gcloud recaptcha keys list 命令。

准备 Android 环境

原生 Android

  1. 下载并安装最新版本的 Android Studio,以准备开发环境。

  2. 确保您有一个应用的最低 Android SDK 值设置为 API 23: Android 6.0 (Marshmallow)。您可以将应用的最低 SDK 版本设置为 API 19,也可以创建新的移动应用。

  3. 如果您要创建新的移动应用,请通过启动新的 Android Studio 项目创建一个测试应用:

    1. 选择 Empty Activity。如果您想在应用中使用 Jetpack Compose,请选择 Empty Compose Activity
    2. 将语言设置为 kotlin
    3. 将最低 SDK 值设置为 API 23: Android 6.0 (Marshmallow)
  4. 确保 Google 的 Maven 代码库 google() 位于项目级层 build.gradle 文件的代码库列表中,如以下代码段所示:

    allprojects {
        repositories {
            google()
        }
    }
    

    如需了解详情,请参阅 Google 的 Maven 制品库

  5. 如需添加 reCAPTCHA API 依赖项,请将以下构建规则添加到应用级层 build.gradle 文件的 dependencies 部分。

      implementation 'com.google.android.recaptcha:recaptcha:18.7.0-beta01'
    

    如需详细了解如何在 Android 应用中添加依赖项,请参阅添加 build 依赖项

  6. 在应用的清单文件(例如 AndroidManifest.xml)中的第一个 <manifest> 标记与第一个 <application> 标记之间添加互联网权限。您需要此权限,因为 reCAPTCHA API 涉及网络操作。

    <manifest ...>
    
        <uses-permission android:name="android.permission.INTERNET" />
    
        <application ...>
        ...
      </application>
    </manifest>
    
  7. 如果您想在新项目中使用 AndroidX 库,请将 SDK 编译为 Android 9.0 或更高版本,并将以下代码段添加到 gradle.properties

    android.useAndroidX=true
    android.enableJetifier=true
    

    如需了解详情,请参阅迁移至 AndroidX

Flutter

如需详细了解如何通过 Flutter 使用 reCAPTCHA,请参阅 Flutter 文档

React Native

如需详细了解如何通过 React Native 使用 reCAPTCHA,请参阅 React Native 文档

将 reCAPTCHA 与 Android 应用集成

  1. 使用您为 Android 应用创建的 reCAPTCHA 密钥 (KEY_ID) 实例化客户端。

    Kotlin 与 fetchClient

    fetchClient 方法会立即返回一个客户端,并开始在后台初始化 SDK。在网络故障时,它会重试与 reCAPTCHA 服务器的通信。

    class CustomApplication : Application() {
    
        private lateinit var recaptchaClient: RecaptchaClient
    
        override fun onCreate() {
          super.onCreate()
          initializeRecaptchaClient()
        }
    
        private fun initializeRecaptchaClient() {
          lifecycleScope.launch {
            try {
              recaptchaClient = Recaptcha.fetchClient(application, "KEY_ID")
            } catch(e: RecaptchaException) {
              // Handle errors ...
              // See "Handle errors" section
            }
          }
        }
    }
    

    使用 fetchClient 的 Java

    public final class CustomApplication extends Application {
      @Nullable private RecaptchaTasksClient recaptchaTasksClient = null;
    
      @Override
      protected void onCreate() {
        super.onCreate();
        initializeRecaptchaClient();
      }
    
      private void initializeRecaptchaClient() {
        Recaptcha
          .fetchTaskClient(getApplication(), "KEY_ID")
          .addOnSuccessListener(
              this,
              new OnSuccessListener<RecaptchaTasksClient>() {
                @Override
                public void onSuccess(RecaptchaTasksClient client) {
                  MainActivity.this.recaptchaTasksClient = client;
                }
              })
          .addOnFailureListener(
              this,
              new OnFailureListener() {
                @Override
                public void onFailure(@NonNull Exception e) {
                  // Handle errors ...
                  // See "Handle errors" section
                }
              });
      }
    }
    

    SDK 的初始化可能需要几秒钟才能完成。为了减少此延迟时间,请尽早初始化客户端,例如在自定义 Application 类的 onCreate() 调用期间。您不应让界面元素阻塞 reCAPTCHA SDK。

  2. 对于应用中使用 reCAPTCHA 保护的每项操作,请调用 execute 方法并传递 RecaptchaAction。reCAPTCHA 提供了一组内置操作,您也可以根据需要创建自定义操作。

    以下代码段展示了如何使用 execute 保护 LOGIN 操作。

    Kotlin

    private fun executeLoginAction() {
      lifecycleScope.launch {
        recaptchaClient
          .execute(RecaptchaAction.LOGIN)
          .onSuccess { token ->
            // Handle success ...
            // See "What's next" section for instructions
            // about handling tokens.
          }
          .onFailure { exception ->
            // Handle errors ...
          }
      }
    }
    

    Java

    private void executeLoginAction(View v) {
      assert recaptchaTasksClient != null;
      recaptchaTasksClient
        .executeTask(RecaptchaAction.LOGIN)
        .addOnSuccessListener(
            this,
            new OnSuccessListener<String>() {
              @Override
              public void onSuccess(String token) {
                // Handle success ...
                // See "What's next" section for instructions
                // about handling tokens.
              }
            })
        .addOnFailureListener(
            this,
            new OnFailureListener() {
              @Override
              public void onFailure(@NonNull Exception e) {
                // Handle errors ...
              }
            });
    }
    

从 getClient 方法迁移到 fetchClient 方法

fetchClient 方法会返回一个 RecaptchaClient,用于在网络连接失败时重试初始化。如果应用在创建客户端时没有网络访问权限,客户端会不断重试,并在获得网络连接后成功初始化。

如果您调用 execute(timeout) 时客户端尚未准备就绪,则客户端会先尝试初始化,然后再返回令牌或 RecaptchaErrorCode

以下示例展示了如何从 getClient 迁移到 fetchClient

Kotlin

// Migrate from getClient
private fun initializeWithGetClient() {
  lifecycleScope.launch {
    Recaptcha.getClient(application, "KEY_ID")
      .onSuccess { client ->
        recaptchaClient = client
      }
      .onFailure { exception ->
        // Handle errors ...
      }
  }
}

 // Migrate to fetchClient
private fun initializeWithFetchClient() {
  lifecycleScope.launch {
    try {
      recaptchaClient = Recaptcha.fetchClient(application, "KEY_ID")
    } catch(e: RecaptchaException){
      // Handle errors ...
    }
  }
}

Java

  // Migrate from getTasksClient
  private void initializeWithGetTasksClient() {
    Recaptcha
      .getTasksClient(getApplication(), "KEY_ID")
      .addOnSuccessListener(
          this,
          new OnSuccessListener<RecaptchaTasksClient>() {
            @Override
            public void onSuccess(RecaptchaTasksClient client) {
              recaptchaTasksClient = client;
            }
          })
      .addOnFailureListener(
          this,
          new OnFailureListener() {
            @Override
            public void onFailure(@NonNull Exception e) {
              // Handle errors ...
            }
          });
  }

  // Migrate to fetchTaskClient
  private void initializeWithFetchTaskClient() {
    Recaptcha
      .fetchTaskClient(getApplication(), "KEY_ID")
      .addOnSuccessListener(
          this,
          new OnSuccessListener<RecaptchaTasksClient>() {
            @Override
            public void onSuccess(RecaptchaTasksClient client) {
              recaptchaTasksClient = client;
            }
          })
      .addOnFailureListener(
          this,
          new OnFailureListener() {
            @Override
            public void onFailure(@NonNull Exception e) {
              // Handle errors ...
            }
          });
  }

为 API 调用设置超时

您可以使用 withTimeout 属性为 execute API 指定超时值。

Kotlin

  • 在调用 execute 时设置超时。

        lifecycleScope.launch {
          recaptchaClient
            .execute(RecaptchaAction.LOGIN(), timeout = 10000L)
            .onSuccess { token ->
              // Handle success ...
              // See "What's next" section for instructions
              // about handling tokens.
            }
            .onFailure { exception ->
              // Handle errors ...
              // See "Handle errors" section
            }
        }
    

    此代码段将 execute 的超时设置为 10 秒。

Java

  • 在调用 execute 时设置超时。

      recaptchaTasksClient
        .executeTask(RecaptchaAction.custom("redeem"), 10000L)
        .addOnSuccessListener(
            this,
            new OnSuccessListener<String>() {
              @Override
              public void onSuccess(String token) {
                // Handle success ...
                // See "What's next" section for instructions
                // about handling tokens.
              }
            })
        .addOnFailureListener(
            this,
            new OnFailureListener() {
              @Override
              public void onFailure(@NonNull Exception e) {
                // Handle errors ...
                // See "Handle errors" section
              }
            });
    

    此代码段将 execute 的超时设置为 10 秒。

处理错误

如果您的应用无法成功与 reCAPTCHA 服务通信,则可能是因为 API 遇到了错误。您必须在应用中添加逻辑,以妥善处理此类错误。

如需详细了解常见 API 错误的缓解措施,请参阅 RecaptchaErrorCode

API 参考文档

如需 Android 版 reCAPTCHA API 的完整参考信息,请参阅 com.google.android.recaptcha

后续步骤

  • 如需评估 reCAPTCHA 响应令牌,请创建评估