https://a.storyblok.com/f/270183/186542/4eb60dd2fd/passwordless-authentication_1200x628.jpg

Adicione a autenticação de dois fatores (2FA) a um aplicativo Android com o Nexmo e o Firebase Login

Publicado em May 17, 2021

Tempo de leitura: 7 minutos

O Guia de Início Rápido do Firebase Auth oferece um ótimo tutorial sobre como adicionar autenticação ao seu aplicativo, mas sem a autenticação de dois fatores (2FA), ele fica um pouco inseguro! Adicionar uma camada extra de segurança ao seu aplicativo é simples usando o SDK do Nexmo Verify. Vamos começar!

Baixe o aplicativo de exemplo

Comece clonando o repositório do GitHub no seu Terminal. O repositório original está em constante mudança; portanto, você pode clonar o branch inicial do tutorial a partir de um repositório bifurcado da nexmo-community.

git clone https://github.com/nexmo-community/quickstart-android.git

Crie um novo projeto no console do Firebase

Faça login no Firebase com sua conta do Google e acesse o console. Crie um novo projeto, atribuindo um nome a ele e atualizando o país em que você reside. Após a criação, clique na opção “Adicionar o Firebase ao seu aplicativo Android”. Insira o nome do pacote (o padrão para o aplicativo de demonstração é: com.google.firebase.quickstart.auth) e o SHA-1 do certificado de assinatura de depuração. Ignore o arquivo “google-services.json” que foi baixado, pois você precisará baixar uma nova versão assim que adicionarmos os métodos de login OAuth ao aplicativo. Você não precisa editar os arquivos build.gradle, pois isso já foi feito para você no projeto de exemplo.

Add Firebase to Android App

Configurar métodos de login

O aplicativo de exemplo vem com os seguintes métodos de login: login por e-mail/senha, login anônimo e logins via OAuth. Ambos os provedores OAuth (Google e Twitter) precisam ser configurados, e a chave e o segredo da API de login do Twitter devem ser inseridos no arquivo ‘ids.xml’. Se tiver dificuldade para encontrá-lo, procure o arquivo usando a ferramenta de busca no canto superior direito do Android Studio. Depois que os métodos de autenticação estiverem configurados, acesse as configurações do seu projeto, baixe o arquivo ‘google-services.json’ e adicione-o à pasta do aplicativo na visualização do projeto.

  • E-mail e login anônimo: habilite ambos os métodos na seção “Autenticação” do console do Firebase.

  • Google: O Google Sign In deve ser configurado para seu aplicativo Android depois que você adicionar o certificado de assinatura SHA-1 de depuração no console do Firebase. Habilite o método Google OAuth na seção “Autenticação” do console.

  • Twitter: No console do Firebase, habilite o Twitter para autenticação. Em seguida, crie um novo aplicativo no Portal do Desenvolvedor do Twitter. Copie a URL de retorno de chamada (disponível na seção “Autenticação do Twitter” do console do Firebase) e insira-a no campo correspondente para concluir a criação do aplicativo do Twitter. Por fim, acesse as “Configurações do aplicativo do Twitter” e clique em “Gerenciar chaves e tokens de acesso”. Copie a chave de consumidor (Chave de API) e o segredo de consumidor (Segredo de API) no console do Firebase e no arquivo ‘ids.xml’.

Create New Twitter Application

Abrir e atualizar projeto

No Android Studio, escolha a opção para abrir um projeto existente. Navegue até o local onde o repositório foi clonado e selecione a pasta “auth”, localizada dentro da pasta “quickstart-android”. Você precisará atualizar o Android SDK para a versão 25, as ferramentas de compilação para a versão 25.0.0 e também atualizar a versão do JDK para 1.8, pois essas atualizações são necessárias para compilar os arquivos Gradle com sucesso. Assim que o projeto for carregado no Android Studio, instale as dependências que estiverem faltando e sincronize o projeto para corrigir os erros. Crie um AVD que utilize a API 24 para executar o aplicativo corretamente ao final do tutorial. Por fim, atualize os Google Play Services do seu projeto em Ferramentas > Android > Gerenciador de SDK > Ferramentas do SDK para a versão 38.

Criar uma aplicação Nexmo

Depois de criar um Account no Nexmo, você será redirecionado para o painel do Nexmo. Clique na aba “Verify” e, em “SDK”, clique no link “Seus aplicativos”. Crie um novo aplicativo (com o “Tempo máximo de inatividade” definido como “Imediato”) e anote o ID do aplicativo e o segredo compartilhado. O “Tempo máximo de inatividade” é uma configuração que determina por quanto tempo o usuário permanecerá verificado.

Create Nexmo Application

Adicione as credenciais do Nexmo (assim como as do OAuth, caso não tenha feito isso na etapa anterior) ao arquivo 'ids.xml'.

NEXMO-APPLICATION-ID NEXMO-SHARED-SECRET TWITTER_CONSUMER_KEY TWITTER_CONSUMER_SECRET

Adicione a dependência do Nexmo ao arquivo Build.gradle do aplicativo

Adicione a seguinte linha de código ao arquivo Build.gradle do seu aplicativo para incluir o SDK do Nexmo Verify como uma dependência. Sincronize o arquivo Gradle para resolver quaisquer dependências ausentes.

compile 'com.nexmo:verify:4.0.0'

Adicione uma nova classe para o Nexmo Client

Crie uma nova classe no seu projeto chamada “TwoFactorApplication.java” e insira o código a seguir no arquivo. Aqui, você cria o cliente Nexmo e fornece a ele os valores que armazenou anteriormente no arquivo “ids.xml”.

package com.google.firebase.quickstart.auth;

import android.app.Application;
import android.content.Context;
Import android.util.Log;
import com.nexmo.sdk.NexmoClient;
import com.nexmo.sdk.core.client.ClientBuilderException;
import com.nexmo.sdk.verify.client.VerifyClient;

public class TwoFactorApplication extends Application {
private VerifyClient verifyClient;
private NexmoClient nexmoClient;
private boolean verified;
private static final String TAG = “TWOFACTORAPPLICATION”;
public VerifyClient getVerifyClient(boolean verifiedValue) {
verified = verifiedValue;
return this.verifyClient;
}
@Override
public void onCreate() {
super.onCreate();
acquireVerifyClient();
}
public void acquireVerifyClient() {
Context context = getApplicationContext();
try {
this.nexmoClient = new NexmoClient.NexmoClientBuilder()
.context(context)
.applicationId(getResources().getString(R.string.nexmo_application_id))
.sharedSecretKey(getResources().getString(R.string.nexmo_shared_secret))
.build();
} catch (ClientBuilderException e) {
e.printStackTrace();
Log.d(TAG, e.toString());
return;
}
this.verifyClient = new VerifyClient(nexmoClient);
}
}

No arquivo “AndroidManifest.xml”, adicione as permissões necessárias para o Verify SDK e o nome do aplicativo à tag “application”:

<application
android:name="com.google.firebase.quickstart.auth.TwoFactorApplication"

Adicione o código a seguir à BaseActivity

Declare as seguintes variáveis na BaseActivity:

  • aplicativo (do tipo: TwoFactorApplication)

  • verificado (tipo: booleano)

No método ‘onCreate()’, faça a conversão do contexto da aplicação retornado pela chamada a ‘this.getApplication();’. Isso retorna a aplicação à qual a atividade pertence (TwoFactorApplication). Em seguida, criamos um método chamado ‘addVerificationListener’ para atuar como ouvinte, a fim de dar continuidade ao fluxo de trabalho do aplicativo após uma verificação 2FA bem-sucedida. Dentro desse método, obtemos o `VerifyClient` fornecido pela biblioteca Nexmo e chamamos o método `addVerifyListener()`.

//Import Statements
import java.io.IOException;
import com.nexmo.sdk.verify.client.VerifyClient;
import com.nexmo.sdk.verify.event.UserObject;
import com.nexmo.sdk.verify.event.VerifyClientListener;
import com.nexmo.sdk.verify.event.VerifyError;
Import android.os.Bundle;

//Declaration
public TwoFactorApplication twoFactorApp;
protected boolean verified;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
twoFactorApp = (TwoFactorApplication) this.getApplication();
}

protected void addVerificationListener() {
twoFactorApp.getVerifyClient(verified).addVerifyListener(new VerifyClientListener() {
@Override
public void onVerifyInProgress(VerifyClient verifyClient, UserObject user) {
}
@Override
public void onUserVerified(VerifyClient verifyClient, UserObject user) {
verified = true;
}
@Override
public void onError(VerifyClient verifyClient, VerifyError errorCode, UserObject user) {
}
@Override
public void onException(IOException exception) {
}
});
}

Atualizar o código do GoogleSignInActivity

Mova a chamada ao método 'signIn()' da função onClick para o método ‘onStart()’ se o valor de ‘verified’ for igual a true. Em vez disso, quando o usuário clicar no botão de login, inicie a interface de usuário gerenciada pelo Verify SDK e chame o método 'addVerificationListener()'. Por fim, altere o valor de “verified” para “false” quando a Activity for encerrada, para garantir que o usuário precise fazer login todas as vezes.

@Override
public void onStart() {
super.onStart();
if (verified == true) {
signIn();
}
mAuth.addAuthStateListener(mAuthListener);
}

@Override
public void onStop() {
super.onStop();
verified = false;
mAuth.signOut();
if (mAuthListener != null) {
mAuth.removeAuthStateListener(mAuthListener);
}
}

@Override
public void onClick(View v) {
if (i == R.id.sign_in_button) {
twoFactorApp.getVerifyClient(verified).getVerifiedUserFromDefaultManagedUI();
addVerificationListener();
} else if (i == R.id.sign_out_button) {
signOut();
} else if (i == R.id.disconnect_button) {
revokeAccess();
}
}

Atualizar o código da EmailPasswordActivity

Assim como na etapa anterior, mova a chamada do método de login da função `onClick` para o método `onStart()`. Em vez disso, inicie a interface de usuário gerenciada pelo Verify SDK e chame o método `verificationCallback()` quando o usuário clicar no botão de login. Mais uma vez, altere “verified” para false no método `onStop()`.

@Override
public void onStart() {
super.onStart();
if (verified == true) {
signIn(mEmailField.getText().toString(), mPasswordField.getText().toString());
}
mAuth.addAuthStateListener(mAuthListener);
}

@Override
public void onStop() {
super.onStop();
verified = false;
mAuth.signOut();
if (mAuthListener != null) {
mAuth.removeAuthStateListener(mAuthListener);
}
}

@Override
public void onClick(View v) {
if (i == R.id.sign_in_button) {
twoFactorApp.getVerifyClient(verified).getVerifiedUserFromDefaultManagedUI();
addVerificationListener();
} else if (i == R.id.sign_out_button) {
signOut();
} else if (i == R.id.disconnect_button) {
revokeAccess();
}
}

private void signOut() {
mAuth.signOut();
verified = false;
updateUI(null);
}

Atualizar o código da AnonymousAuthActivity

Mais uma vez, transferimos a chamada do método de login de ‘onClick’ para o método ‘onStart()’, a ser chamado caso o usuário tenha sido verificado. Quando o usuário clicar no botão “Entrar”, acione a interface de usuário gerenciada ‘Verify’ e chame o método ‘addVerificationListener()’ ao clicar no botão de login.

@Override
public void onStart() {
super.onStart();
mAuth.addAuthStateListener(mAuthListener);
if (verified) {
signInAnonymously();
}
}

@Override
public void onStop() {
super.onStop();
mAuth.signOut();
verified = false;
if (mAuthListener != null) {
mAuth.removeAuthStateListener(mAuthListener);
}
}

private void signOut() {
mAuth.signOut();
verified = false;
updateUI(null);
}

@Override
public void onClick(View v) {
int i = v.getId();
if (i == R.id.button_anonymous_sign_in) {
twoFactorApp.getVerifyClient(verified).getVerifiedUserFromDefaultManagedUI();
addVerificationListener();
} else if (i == R.id.button_anonymous_sign_out) {
signOut();
} else if (i == R.id.button_link_account) {
linkAccount();
}
}

Atualizar o código da TwitterLoginActivity

O fluxo de login da TwitterLoginActivity é um pouco mais complexo do que o das atividades de login anteriores. O botão de login do Twitter inicia a sequência de login via OAuth do Twitter. Aqui, você permite que o usuário continue com o fluxo de login após ter fornecido o código PIN correto (onUserVerified).

@Override
public void onStart() {
super.onStart();
mAuth.addAuthStateListener(mAuthListener);
if(!verified) {
twoFactorApp.getVerifyClient(verified).getVerifiedUserFromDefaultManagedUI();
addVerificationListener();
}
}

@Override
public void onStop() {
super.onStop();
verified = false;
mAuth.signOut();
if (mAuthListener != null) {
mAuth.removeAuthStateListener(mAuthListener);
}
}

private void signOut() {
mAuth.signOut();
verified = false;
Twitter.logOut();
updateUI(null);
}

mLoginButton.setCallback(new Callback() {
@Override
public void success(Result result) {
Log.d(TAG, "twitterLogin:success" + result);
verified = true;
handleTwitterSession(result.data);
}
@Override
public void failure(TwitterException exception) {
Log.w(TAG, "twitterLogin:failure", exception);
updateUI(null);
}
});

Agora, todos os provedores OAuth, juntamente com os métodos de login por e-mail/senha e anônimo, possuem um fluxo que garante que o usuário conclua o segundo fator de autenticação para acessar a Account. A versão deste tutorial com 2FA habilitada está disponível no ramo “final” do repositório.

Chooser Activity Google Sign In Screen Twitter Login Screen Email Login Screen Anonymous Login Screen

O Verify SDK permite que você dedique mais tempo ao desenvolvimento do seu aplicativo, oferecendo uma solução de interface de usuário gerenciada que possibilita a realização de solicitações de verificação com segurança e facilidade. Adoraria receber seu contato caso tenha dúvidas ou sugestões. Envie-me um tweet https://twitter.com/sidsharma_27 ou me mande um e-mail diretamente.

Compartilhar:

https://a.storyblok.com/f/270183/150x150/a3d03a85fd/placeholder.svg
Sidharth Sharma