Integrar o reCAPTCHA Enterprise a apps Android

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

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

Antes de começar

  1. Prepare seu ambiente para o reCAPTCHA Enterprise.

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

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

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

      1. Acesse a página do reCAPTCHA Enterprise.

        Acessar o reCAPTCHA Enterprise

      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 atual usando a API REST, use o método projects.keys.list.
    • Para copiar o ID de uma chave atual com 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. Confira se você tem um app com o valor mínimo do SDK do Android definido como API 19: Android 4.4 (KitKat). Você pode definir o SDK mínimo do seu 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. Para usar o Jetpack Compose no app, selecione Atividade do Compose vazia.
    2. Defina o idioma como kotlin.
    3. Defina o valor mínimo do SDK como API 19: Android 4.4 (KitKat).
  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 a seção Repositório Maven do Google.

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

      implementation 'com.google.android.recaptcha:recaptcha:18.5.0-beta02'
    

    Para saber mais sobre como adicionar dependências em apps Android, consulte Adicionar dependências de build.

  6. Adicione permissão de Internet entre a primeira tag <manifest> e a primeira tag <application> no manifesto do app (por exemplo, AndroidManifest.xml). Essa permissão é necessária porque a API reCAPTCHA Enterprise 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 Enterprise no Flutter, consulte a documentação do Flutter (link em inglês).

ReactNative

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

Integrar o reCAPTCHA Enterprise ao seu app Android

  1. Instancie um cliente usando a chave reCAPTCHA (KEY_ID) que você criou para seu app Android.

    Kotlin

    class MainActivity : AppCompatActivity() {
    
        private lateinit var recaptchaClient: RecaptchaClient
    
        override fun onCreate(savedInstanceState: Bundle?) {
          super.onCreate(savedInstanceState)
          setContentView(R.layout.activity_main)
          initializeRecaptchaClient()
          // ... rest of onCreate code
        }
    
        private fun initializeRecaptchaClient() {
          lifecycleScope.launch {
            Recaptcha.getClient(application, "KEY_ID")
              .onSuccess { client ->
                recaptchaClient = client
              }
              .onFailure { exception ->
                // Handle communication errors ...
                // See "Handle communication errors" section
              }
          }
        }
    
        // ... rest of activity code.
    }
    

    Java

    public final class MainActivity extends Activity {
      @Nullable private RecaptchaTasksClient recaptchaTasksClient = null;
    
      @Override
      protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initializeRecaptchaClient();
        // ... rest of onCreate code
      }
    
      private void initializeRecaptchaClient() {
        Recaptcha
          .getTasksClient(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 communication errors ...
                  // See "Handle communication errors" section
                }
              });
      }
    
      // ... rest of activity code.
    }
    
  2. Para cada ação do app protegida pelo reCAPTCHA Enterprise, chame o método execute transmitindo uma RecaptchaAction. O reCAPTCHA Enterprise 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 communication errors ...
            // See "Handle communication errors" section
          }
      }
    }
    

    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 communication errors ...
                // See "Handle communication errors" section
              }
            });
    }
    

O snippet de código de exemplo abaixo mostra uma integração completa dos métodos getClient() e execute() em um único app Activity:

Kotlin

class MainActivity : AppCompatActivity() {

  private lateinit var recaptchaClient: RecaptchaClient

  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
    initializeRecaptchaClient()
    findViewById<View>(R.id.btn_login).setOnClickListener { executeLoginAction() }
    findViewById<View>(R.id.btn_redeem).setOnClickListener { executeRedeemAction() }
  }

  private fun initializeRecaptchaClient() {
    lifecycleScope.launch {
      Recaptcha.getClient(application, "KEY_ID")
        .onSuccess { client ->
          recaptchaClient = client
        }
        .onFailure { exception ->
          // Handle communication errors ...
          // See "Handle communication errors" section
        }
    }
  }

  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 communication errors ...
          // See "Handle communication errors" section
        }
    }
  }

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

Java

public final class MainActivity extends Activity {
  @Nullable private RecaptchaTasksClient recaptchaTasksClient = null;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    initializeRecaptchaClient();
    findViewById(R.id.btn_login).setOnClickListener(this::executeLoginAction);
    findViewById(R.id.btn_redeem).setOnClickListener(this::executeRedeemAction);
  }

  private void initializeRecaptchaClient() {
    Recaptcha
      .getTasksClient(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 communication errors ...
              // See "Handle communication errors" section
            }
          });
  }

  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 communication errors ...
              // See "Handle communication errors" section
            }
          });
  }

  private void executeRedeemAction(View v) {
    assert recaptchaTasksClient != null;
    recaptchaTasksClient
      .executeTask(RecaptchaAction.custom("redeem"))
      .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 communication errors ...
              // See "Handle communication errors" section
            }
          });
  }
}

Definir um tempo limite para chamadas de API

Especifique um valor de tempo limite para as APIs getClient e execute usando a propriedade timeout de cada API.

Um tempo limite padrão de 10 segundos é usado para getClient e de 10 segundos para APIs execute.

Kotlin

  • Defina o tempo limite ao chamar getClient.

        lifecycleScope.launch {
          Recaptcha.getClient(application, "KEY_ID", timeout = 20000L)
            .onSuccess { client ->
              recaptchaClient = client
            }
            .onFailure { exception ->
              // Handle communication errors ...
              // See "Handle communication errors" section
            }
        }
    

    Este snippet de código define o tempo limite de getClient como 20 segundos.

  • Defina 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 communication errors ...
              // See "Handle communication errors" section
            }
        }
    

    Este snippet de código define o tempo limite de execute como 10 segundos.

Java

  • Defina o tempo limite ao chamar getClient.

      Recaptcha
        .getTasksClient(getApplication(), "KEY_ID", 20000L)
        .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 communication errors ...
                // See "Handle communication errors" section
              }
            });
    

    Este snippet de código define o tempo limite de getClient como 20 segundos.

  • Defina 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 communication errors ...
                // See "Handle communication errors" section
              }
            });
    

    Este snippet de código define o tempo limite de execute como 10 segundos.

Tratar erros de comunicação

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

Para mais detalhes sobre as 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.