Integra reCAPTCHA en apps para Android

En esta página, se explica cómo integrar reCAPTCHA en tu app para Android.

Si deseas proporcionar desafíos visuales para el tráfico sospechoso, puedes usar la API de reCAPTCHA de SafetyNet.

El SDK usa reflexión y código dinámico para permitir la modificación y mejora del sistema de detección en las aplicaciones o los SDKs implementados existentes. El conjunto de clases que están disponibles en el sistema se restringe a una lista controlada para evitar interferencias con la aplicación.

Antes de comenzar

  1. Prepara tu entorno para reCAPTCHA.

  2. Crea una clave de reCAPTCHA para la plataforma de apps para Android.

    Como alternativa, puedes copiar el ID de una clave reCAPTCHA existente para Android. Para ello, sigue uno de los siguientes pasos:

    • Para copiar el ID de una clave existente desde la consola de Google Cloud, haz lo siguiente:

      1. Ve a la página de reCAPTCHA.

        Ve a reCAPTCHA

      2. En la lista de claves de reCAPTCHA, mantén el puntero sobre la clave que deseas copiar y, luego, haz clic en .
    • Para copiar el ID de una clave existente con la API de REST, usa el método projects.keys.list.
    • Para copiar el ID de una clave existente con la CLI de gcloud, usa el comando gcloud recaptcha keys list.

Prepara tu entorno de Android

Android nativo

  1. Para preparar tu entorno de desarrollo, descarga e instala la versión más reciente de Android Studio.

  2. Asegúrate de tener una app con el valor mínimo del SDK de Android configurado en API 23: Android 6.0 (Marshmallow). Puedes establecer el SDK mínimo de tu app en la API 19 o crear una app para dispositivos móviles nueva.

  3. Si estás creando una nueva app para dispositivos móviles, inicia un proyecto nuevo de Android Studio para crear una aplicación de prueba:

    1. Selecciona Empty Activity. Si quieres usar Jetpack Compose en tu app, elige Actividad de Compose vacía.
    2. Establece el lenguaje como kotlin.
    3. Establece el valor de SDK mínimo en API 23: Android 6.0 (Marshmallow).
  4. Asegúrate de que el repositorio google() de Maven de Google esté en la lista de repositorios del archivo build.gradle a nivel de proyecto, como se muestra en el siguiente fragmento:

    allprojects {
        repositories {
            google()
        }
    }
    

    Para obtener más información, consulta el repositorio de Maven de Google.

  5. Para agregar la dependencia de la API de reCAPTCHA, agrega la siguiente regla de compilación a la sección dependencies del archivo build.gradle a nivel de la app.

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

    Para obtener más información sobre cómo agregar dependencias en apps para Android, consulta Cómo agregar dependencias de compilación.

  6. Agrega el permiso de Internet entre la primera etiqueta <manifest> y la primera etiqueta <application> en el manifiesto de tu aplicación (por ejemplo, AndroidManifest.xml). Este permiso es obligatorio porque la API de reCAPTCHA incluye operaciones de red.

    <manifest ...>
    
        <uses-permission android:name="android.permission.INTERNET" />
    
        <application ...>
        ...
      </application>
    </manifest>
    
  7. Si deseas usar bibliotecas de AndroidX en tu proyecto nuevo, compila el SDK para Android 9.0 o versiones posteriores y agrega el siguiente fragmento de código a tu gradle.properties.

    android.useAndroidX=true
    android.enableJetifier=true
    

    Para obtener más información, consulta Cómo migrar a AndroidX.

Flutter

Para obtener instrucciones detalladas sobre el uso de reCAPTCHA a través de Flutter, consulta la documentación de Flutter.

React Native

Si deseas obtener instrucciones detalladas para usar reCAPTCHA a través de React Native, consulta la documentación de React Native.

Integra reCAPTCHA en tu app para Android

  1. Crea una instancia de un cliente con la clave de reCAPTCHA (KEY_ID) que creaste para tu app para Android.

    Kotlin con fetchClient

    El método fetchClient muestra un cliente de inmediato y comienza a inicializar el SDK en segundo plano. Vuelve a intentar la comunicación con el servidor de reCAPTCHA en caso de fallas de red.

    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
            }
          }
        }
    }
    

    Java con fetchClient

    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
                }
              });
      }
    }
    

    La inicialización del SDK puede tardar varios segundos en completarse. Para mitigar esta latencia, inicializa el cliente lo antes posible, por ejemplo, durante la llamada onCreate() de una clase Application personalizada. No debes hacer que los elementos de la IU se bloqueen en el SDK de reCAPTCHA.

  2. Para cada acción de tu app que esté protegida con reCAPTCHA, llama al método execute y pasa un RecaptchaAction. reCAPTCHA proporciona un conjunto integrado de acciones y, si es necesario, puedes crear acciones personalizadas.

    En el siguiente fragmento de código, se muestra cómo usar execute para proteger una acción 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 ...
              }
            });
    }
    

Cómo migrar del método getClient al método fetchClient

El método fetchClient muestra un RecaptchaClient que vuelve a intentar la inicialización en caso de fallas de red. Si la app no tiene acceso a la red cuando se crea el cliente, este sigue reintentando y se inicializa correctamente cuando se adquiere una red.

Si llamas a execute(timeout) y el cliente aún no está listo, intentará inicializarse antes de mostrar un token o un RecaptchaErrorCode.

En el siguiente ejemplo, se muestra cómo migrar de getClient a 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 ...
            }
          });
  }

Establece un tiempo de espera para las llamadas a la API

Puedes especificar un valor de tiempo de espera para las APIs de execute con la propiedad withTimeout.

Kotlin

  • Establece el tiempo de espera cuando llames a 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
            }
        }
    

    Este fragmento de código establece el tiempo de espera de execute en 10 segundos.

Java

  • Establece el tiempo de espera cuando llames a 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
              }
            });
    

    Este fragmento de código establece el tiempo de espera de execute en 10 segundos.

Soluciona errores

Si la app no se puede comunicar con el servicio de reCAPTCHA correctamente, es posible que la API haya detectado un error. Debes agregar lógica en tu app para controlar estos errores.

Para obtener más detalles sobre las mitigaciones de errores comunes de la API, consulta RecaptchaErrorCode.

Referencia de API

Para obtener una referencia completa de la API de reCAPTCHA para Android, consulta com.google.android.recaptcha.

¿Qué sigue?

  • Para evaluar el token de respuesta de reCAPTCHA, crea una evaluación.