Integrar o reCAPTCHA a apps Android

Esta página explica como integrar o reCAPTCHA ao seu app Android.

Se você quiser oferecer desafios visuais para tráfego suspeito, use a API SafetyNet reCAPTCHA.

O SDK usa reflexão e código dinâmico para permitir a modificação e o refinamento do sistema de detecção nos aplicativos/SDKs implantados. O conjunto de classes disponível no sistema é restrito a uma lista controlada para evitar interferências no aplicativo.

Antes de começar

  1. Prepare seu ambiente para o reCAPTCHA.

  2. Crie uma chave de reCAPTCHA para a plataforma de app Android.

    Como alternativa, é possível copiar o ID de uma chave reCAPTCHA para Android executando uma das seguintes etapas:

    • Para copiar o ID de uma chave existente no console do Google Cloud, faça o seguinte:

      1. Acesse a página do reCAPTCHA.

        Acessar o reCAPTCHA

      2. Na lista de chaves reCAPTCHA, mantenha o ponteiro do mouse sobre a chave que você quer copiar e clique em .
    • Para copiar o ID de uma chave usando a API REST, use o método projects.keys.list.
    • Para copiar o ID de uma chave usando a CLI gcloud, use o comando gcloud recaptcha keys list.

Preparar o ambiente Android

Android nativo

  1. Prepare seu ambiente de desenvolvimento fazendo o download e instalando a versão mais recente do Android Studio.

  2. Verifique se você tem um app com o valor mínimo do SDK do Android definido como API 23: Android 6.0 (Marshmallow). Você pode definir o SDK mínimo do app como a API 19 ou criar um novo app para dispositivos móveis.

  3. Se você estiver criando um novo app para dispositivos móveis, crie um aplicativo de teste iniciando um novo projeto do Android Studio:

    1. Selecione Empty Activity. Se você quiser usar o Jetpack Compose no app, escolha Atividade vazia do Compose.
    2. Defina a linguagem como kotlin.
    3. Defina o valor do SDK mínimo como API 23: Android 6.0 (Marshmallow).
  4. Verifique se o repositório Maven do Google google() está na lista de repositórios no arquivo build.gradle do projeto, conforme mostrado no snippet a seguir:

    allprojects {
        repositories {
            google()
        }
    }
    

    Para mais informações, consulte o Repositório Maven do Google.

  5. Para adicionar a dependência da API reCAPTCHA, adicione a seguinte regra de build à seção dependencies do arquivo build.gradle no nível do app.

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

    Para mais informações sobre como adicionar dependências em apps Android, consulte Adicionar dependências de build.

  6. Adicione a permissão de Internet entre a primeira tag <manifest> e a primeira tag <application> no manifesto do aplicativo (por exemplo, AndroidManifest.xml). Essa permissão é obrigatória porque a API reCAPTCHA envolve operações de rede.

    <manifest ...>
    
        <uses-permission android:name="android.permission.INTERNET" />
    
        <application ...>
        ...
      </application>
    </manifest>
    
  7. Se você quiser usar bibliotecas AndroidX no seu novo projeto, compile o SDK para o Android 9.0 ou versão mais recente e adicione o seguinte snippet de código ao gradle.properties.

    android.useAndroidX=true
    android.enableJetifier=true
    

    Para mais informações, consulte Como migrar para o AndroidX.

Flutter

Para instruções detalhadas sobre como usar o reCAPTCHA no Flutter, consulte a documentação do Flutter.

React Native

Para instruções detalhadas sobre como usar o reCAPTCHA no React Native, consulte a documentação do React Native.

Integrar o reCAPTCHA ao seu app Android

  1. Instância um cliente usando a chave reCAPTCHA (KEY_ID) que você criou para o app Android.

    Kotlin com fetchClient

    O método fetchClient retorna um cliente imediatamente e começa a inicializar o SDK em segundo plano. Ele tenta novamente a comunicação com o servidor reCAPTCHA em falhas de rede.

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

    A inicialização do SDK pode levar vários segundos para ser concluída. Para reduzir essa latência, inicialize o cliente o mais cedo possível, por exemplo, durante a chamada onCreate() de uma classe Application personalizada. Não bloqueie elementos da interface no SDK do reCAPTCHA.

  2. Para cada ação do app que é protegida usando o reCAPTCHA, chame o método execute transmitindo uma RecaptchaAction. O reCAPTCHA oferece um conjunto integrado de ações e, se necessário, é possível criar ações personalizadas.

    O snippet de código abaixo mostra como usar execute para proteger uma ação 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 ...
              }
            });
    }
    

Migrar do método getClient para o método fetchClient

O método fetchClient retorna um RecaptchaClient que tenta a inicialização novamente em falhas de rede. Se o app não tiver acesso à rede quando o cliente for criado, o cliente vai continuar tentando e será inicializado quando uma rede for adquirida.

Se você chamar execute(timeout) e o cliente ainda não estiver pronto, ele tentará ser inicializado antes de retornar um token ou um RecaptchaErrorCode.

O exemplo a seguir mostra como migrar de getClient para 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 ...
            }
          });
  }

Definir um tempo limite para chamadas de API

É possível especificar um valor de tempo limite para as APIs execute usando a propriedade withTimeout.

Kotlin

  • Define o tempo limite ao chamar 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 snippet de código define o tempo limite de execute como 10 segundos.

Java

  • Define o tempo limite ao chamar 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 snippet de código define o tempo limite de execute como 10 segundos.

Tratar erros

Se o app não conseguir se comunicar com o serviço reCAPTCHA, talvez seja porque a API encontrou um erro. É necessário adicionar lógica ao app para processar esses erros.

Para mais detalhes sobre mitigações de erros comuns de API, consulte RecaptchaErrorCode.

Referência da API

Para uma referência completa da API reCAPTCHA para Android, consulte com.google.android.recaptcha.

A seguir

  • Para avaliar o token de resposta reCAPTCHA, crie uma avaliação.