Recursos avançados de autenticação

1. Configurar

Acessar o código-fonte

Neste codelab, você vai começar com uma versão quase completa do app de exemplo Friendly Chat. Portanto, a primeira coisa que você precisa fazer é clonar o código-fonte:

$ git clone https://github.com/firebase/codelab-friendlychat-web --branch security

Em seguida, acesse o diretório security-start, onde você vai trabalhar pelo restante deste codelab:

$ cd codelab-friendlychat-web/security-start

Agora, instale as dependências para executar o código. Se você estiver em uma conexão de Internet mais lenta, isso pode levar um ou dois minutos:

$ npm install && (cd functions && npm install)

Conheça este repositório

O diretório security-solution/ contém o código completo do app de exemplo. O diretório security-start é onde você vai trabalhar no codelab e está faltando algumas partes importantes da implementação da autenticação. Os principais arquivos e recursos em security-start/ e security-solution/ são:

  • functions/index.js contém o código do Cloud Functions, e é onde você vai escrever as funções de bloqueio de autenticação.
  • public/: contém os arquivos estáticos do app de chat
  • public/scripts/main.js: onde o código JS do app de chat (src/index.js) é compilado.
  • src/firebase-config.js: contém o objeto de configuração do Firebase usado para inicializar o app de chat.
  • src/index.js: o código JS do seu app de chat

Instalar a CLI do Firebase

O Emulator Suite faz parte da CLI do Firebase (interface de linha de comando), que pode ser instalada na sua máquina com o seguinte comando:

$ npm install -g firebase-tools@latest

Crie o JavaScript com o webpack, que vai criar o main.js no diretório public/scripts/.

webpack build

Em seguida, confirme se você tem a versão mais recente da CLI. Este codelab funciona com a versão 11.14 ou mais recente.

$ firebase --version
11.14.2

Conectar ao seu projeto do Firebase

Se você não tiver um projeto do Firebase, crie um no Console do Firebase. Anote o ID do projeto escolhido, porque ele será necessário mais tarde.

Agora, você precisa conectar esse código ao seu projeto do Firebase. Primeiro, execute o seguinte comando para fazer login na CLI do Firebase:

$ firebase login

Em seguida, execute o comando a seguir para criar um alias de projeto. Substitua $YOUR_PROJECT_ID pelo ID do seu projeto do Firebase.

$ firebase use $YOUR_PROJECT_ID

Agora você já pode executar o app.

2. Executar os emuladores

Nesta seção, você vai executar o app localmente. Isso significa que é hora de inicializar o Pacote de emuladores.

Iniciar os emuladores

No diretório de origem do codelab, execute o seguinte comando para iniciar os emuladores:

$ firebase emulators:start

Isso vai veicular seu app em http://127.0.0.1:5170 e reconstruir continuamente o código-fonte à medida que você faz mudanças. Basta fazer uma atualização forçada (ctrl-shift-r) localmente no navegador para ver as mudanças.

Você vai observar este tipo de saída:

i  emulators: Starting emulators: auth, functions, firestore, hosting, storage
✔  functions: Using node@16 from host.
i  firestore: Firestore Emulator logging to firestore-debug.log
✔  firestore: Firestore Emulator UI websocket is running on 9150.
i  hosting[demo-example]: Serving hosting files from: ./public
✔  hosting[demo-example]: Local server: http://127.0.0.1:5170
i  ui: Emulator UI logging to ui-debug.log
i  functions: Watching "[...]" for Cloud Functions...
✔  functions: Loaded functions definitions from source: beforecreated.
✔  functions[us-central1-beforecreated]: providers/cloud.auth/eventTypes/user.beforeCreate function initialized (http://127.0.0.1:5011/[...]/us-central1/beforecreated).
i  Running script: npm start
 
> security@1.0.0 start
> webpack --watch --progress
[...]
webpack 5.50.0 compiled with 1 warning in 990 ms

Quando a mensagem Todos os emuladores prontos aparecer, o app estará pronto para uso.

3. Implementar a MFA

A MFA foi parcialmente implementada neste repositório. Você vai adicionar o código para primeiro registrar um usuário na MFA e depois solicitar um segundo fator aos usuários registrados na MFA.

No editor, abra o arquivo src/index.js e encontre o método startEnrollMultiFactor(). Adicione o seguinte código para configurar o verificador reCAPTCHA que vai impedir o abuso por telefone. O verificador reCAPTCHA é definido como invisível e não fica visível para os usuários:

async function startEnrollMultiFactor(phoneNumber) {
  const recaptchaVerifier = new RecaptchaVerifier(
    "recaptcha",
    { size: "invisible" },
    getAuth()
  );

Em seguida, encontre o método finishEnrollMultiFactor() e adicione o seguinte para registrar o segundo fator:

// Completes MFA enrollment once a verification code is obtained.
async function finishEnrollMultiFactor(verificationCode) {
  // Ask user for the verification code. Then:
  const cred = PhoneAuthProvider.credential(verificationId, verificationCode);
  const multiFactorAssertion = PhoneMultiFactorGenerator.assertion(cred);
 
  // Complete enrollment.
  await multiFactor(getAuth().currentUser)
    .enroll(multiFactorAssertion)
    .catch(function (error) {
      alert(`Error finishing second factor enrollment. ${error}`);
      throw error;
    });
  verificationId = null;
}

Em seguida, encontre a função signIn e adicione o seguinte fluxo de controle, que pede aos usuários inscritos na MFA para inserir o segundo fator:

async function signIn() {
  // Sign in Firebase using popup auth and Google as the identity provider.
  var provider = new GoogleAuthProvider();
  await signInWithPopup(getAuth(), provider)
    .then(function (userCredential) {
      // User successfully signed in and is not enrolled with a second factor.
    })
    .catch(function (error) {
      if (error.code == "auth/multi-factor-auth-required") {
        multiFactorResolver = getMultiFactorResolver(getAuth(), error);
        displaySecondFactor(multiFactorResolver.hints);
      } else {
        alert(`Error signing in user. ${error}`);
      }
    });
}

O restante da implementação, incluindo as funções invocadas aqui, já está concluído. Para saber como eles funcionam, navegue pelo restante do arquivo.

4. Testar o login com MFA nos emuladores

Agora teste a implementação do MFA. Verifique se os emuladores ainda estão em execução e acesse o app hospedado localmente em localhost:5170. Tente fazer login. Quando for solicitado a fornecer o código da MFA, ele vai aparecer na janela do terminal.

Como os emuladores oferecem suporte total à autenticação multifator, seu ambiente de desenvolvimento pode ser totalmente independente.

Para saber mais sobre a implementação da MFA, consulte nossos documentos de referência.

5. Criar uma função de bloqueio

Alguns aplicativos são destinados ao uso apenas por um grupo específico de usuários. Nesses casos, é importante criar requisitos personalizados para que um usuário se inscreva ou faça login no seu app.

É isso que as funções de bloqueio oferecem: uma maneira de criar requisitos de autenticação personalizados. São Cloud Functions, mas, ao contrário da maioria das funções, eles são executados de forma síncrona quando um usuário tenta se inscrever ou fazer login.

Para criar uma função de bloqueio, abra functions/index.js no editor e encontre a função beforecreated comentada.

Substitua pelo código abaixo, que permite apenas que usuários com um domínio de exemplo.com criem uma conta:

exports.beforecreated = beforeUserCreated((event) => {
  const user = event.data;
  // Only users of a specific domain can sign up.
  if (!user.email || !user.email.endsWith("@example.com")) {
    throw new HttpsError("invalid-argument", "Unauthorized email");
  }
});

6. Teste a função de bloqueio nos emuladores

Para testar a função de bloqueio, verifique se os emuladores estão em execução e faça logout no app da Web em localhost:5170.

Em seguida, tente criar uma conta com um endereço de e-mail que não termine em example.com. A função de bloqueio impede que a operação seja concluída.

Agora, tente de novo com um endereço de e-mail que termine em example.com. A conta será criada.

Com as funções de bloqueio, é possível criar as restrições necessárias para a autenticação. Para saber mais, consulte os documentos de referência.

Resumo

Muito bem! Você adicionou a autenticação multifator a um app da Web para ajudar os usuários a manter a conta segura e criou requisitos personalizados para que eles se inscrevam usando funções de bloqueio. Você merece um GIF!

Um GIF de pessoas do escritório fazendo a dança "raise the roof"