Autenticar usando a Microsoft com JavaScript

Permita que os usuários se autentiquem com o Firebase usando provedores OAuth, como o Microsoft Azure Active Directory. Basta integrar o login genérico do OAuth ao seu app usando o SDK do Firebase para realizar o fluxo de login completo.

Antes de começar

Para fazer login de usuários usando contas da Microsoft (Azure Active Directory e contas pessoais da Microsoft), primeiro ative a Microsoft como um provedor de login do seu projeto do Firebase:

  1. Adicione o Firebase ao seu projeto em JavaScript.
  2. No console do Firebase, abra a seção Auth.
  3. Na guia Método de login, ative o provedor Microsoft.
  4. Adicione o ID do cliente e a Chave secreta do cliente do console do desenvolvedor às configurações do provedor:
    1. Para registrar um cliente OAuth da Microsoft, siga as instruções em Guia de início rápido: como registrar um app com o endpoint do Azure Active Directory v2.0. Observe que esse endpoint oferece suporte para o login de contas pessoais da Microsoft, bem como de contas do Azure Active Directory. Saiba mais sobre o Azure Active Directory v2.0.
    2. Ao registrar apps nesses provedores, registre o domínio *.firebaseapp.com do projeto como o domínio de redirecionamento do seu app.
  5. Clique em Salvar.

Processar o fluxo de login com o SDK do Firebase

Se você está desenvolvendo um app da Web, a maneira mais fácil de autenticar seus usuários com o Firebase usando contas da Microsoft é processando o fluxo de login com o SDK do Firebase para JavaScript.

Para processar o fluxo de login com o SDK do Firebase para JavaScript, siga estas etapas:

  1. Crie uma instância de um OAuthProvider usando o ID do provedor microsoft.com.

    WebWeb
    import { OAuthProvider } from "firebase/auth";
    
    const provider = new OAuthProvider('microsoft.com');
    var provider = new firebase.auth.OAuthProvider('microsoft.com');
  2. Opcional: especifique os parâmetros OAuth personalizados que você quer enviar com a solicitação OAuth.

    WebWeb
    provider.setCustomParameters({
      // Force re-consent.
      prompt: 'consent',
      // Target specific email with login hint.
      login_hint: 'user@firstadd.onmicrosoft.com'
    });
    provider.setCustomParameters({
      // Force re-consent.
      prompt: 'consent',
      // Target specific email with login hint.
      login_hint: 'user@firstadd.onmicrosoft.com'
    });

    Para saber quais parâmetros são aceitos pela Microsoft, consulte a documentação do OAuth da Microsoft. Não é possível transmitir os parâmetros exigidos pelo Firebase com setCustomParameters(). Esses parâmetros são client_id, response_type, redirect_uri, state, scope e response_mode.

    Para permitir que apenas usuários de um determinado locatário do Azure AD façam login no aplicativo, é possível usar o nome de domínio do locatário do Azure AD ou o identificador GUID do locatário. Isso pode ser feito ao especificar o campo "locatário" no objeto de parâmetros personalizados.

    WebWeb
    provider.setCustomParameters({
      // Optional "tenant" parameter in case you are using an Azure AD tenant.
      // eg. '8eaef023-2b34-4da1-9baa-8bc8c9d6a490' or 'contoso.onmicrosoft.com'
      // or "common" for tenant-independent tokens.
      // The default value is "common".
      tenant: 'TENANT_ID'
    });
    provider.setCustomParameters({
      // Optional "tenant" parameter in case you are using an Azure AD tenant.
      // eg. '8eaef023-2b34-4da1-9baa-8bc8c9d6a490' or 'contoso.onmicrosoft.com'
      // or "common" for tenant-independent tokens.
      // The default value is "common".
      tenant: 'TENANT_ID'
    });
  3. Opcional: especifique os outros escopos de OAuth 2.0 além do perfil básico que você quer solicitar ao provedor de autenticação.

    provider.addScope('mail.read');
    provider.addScope('calendars.read');

    Para saber mais, consulte a documentação de permissões e consentimento da Microsoft (em inglês).

  4. Use o objeto de provedor do OAuth para a autenticação no Firebase. É possível solicitar que os usuários façam login com as respectivas contas da Microsoft em uma nova janela pop-up ou pelo redirecionamento à página de login. O método de redirecionamento é bom para dispositivos móveis.

    • Para fazer login com uma janela pop-up, chame signInWithPopup:
    WebWeb
    import { getAuth, signInWithPopup, OAuthProvider } from "firebase/auth";
    
    const auth = getAuth();
    signInWithPopup(auth, provider)
      .then((result) => {
        // User is signed in.
        // IdP data available in result.additionalUserInfo.profile.
    
        // Get the OAuth access token and ID Token
        const credential = OAuthProvider.credentialFromResult(result);
        const accessToken = credential.accessToken;
        const idToken = credential.idToken;
      })
      .catch((error) => {
        // Handle error.
      });
    firebase.auth().signInWithPopup(provider)
      .then((result) => {
        // IdP data available in result.additionalUserInfo.profile.
        // ...
    
        /** @type {firebase.auth.OAuthCredential} */
        var credential = result.credential;
    
        // OAuth access and id tokens can also be retrieved:
        var accessToken = credential.accessToken;
        var idToken = credential.idToken;
      })
      .catch((error) => {
        // Handle error.
      });
    • Para redirecionar os usuários à página de login, chame signInWithRedirect:

    Siga as práticas recomendadas ao usar signInWithRedirect, linkWithRedirect ou reauthenticateWithRedirect.

    WebWeb
    import { getAuth, signInWithRedirect } from "firebase/auth";
    
    const auth = getAuth();
    signInWithRedirect(auth, provider);
    firebase.auth().signInWithRedirect(provider);

    Depois que o usuário fizer login e retornar à página, chame getRedirectResult para saber o resultado do login.

    WebWeb
    import { getAuth, getRedirectResult, OAuthProvider } from "firebase/auth";
    
    const auth = getAuth();
    getRedirectResult(auth)
      .then((result) => {
        // User is signed in.
        // IdP data available in result.additionalUserInfo.profile.
    
        // Get the OAuth access token and ID Token
        const credential = OAuthProvider.credentialFromResult(result);
        const accessToken = credential.accessToken;
        const idToken = credential.idToken;
      })
      .catch((error) => {
        // Handle error.
      });
    firebase.auth().getRedirectResult()
      .then((result) => {
        // IdP data available in result.additionalUserInfo.profile.
        // ...
    
        /** @type {firebase.auth.OAuthCredential} */
        var credential = result.credential;
    
        // OAuth access and id tokens can also be retrieved:
        var accessToken = credential.accessToken;
        var idToken = credential.idToken;
      })
      .catch((error) => {
        // Handle error.
      });

    Se o processo foi concluído, o token de acesso OAuth associado ao provedor pode ser recuperado com o objeto firebase.auth.UserCredential retornado.

    Com o token de acesso OAuth, é possível chamar a API Microsoft Graph.

    Por exemplo, para receber as informações básicas do perfil, é possível chamar a seguinte API REST:

    curl -i -H "Authorization: Bearer ACCESS_TOKEN" https://graph.microsoft.com/v1.0/me

    Ao contrário de outros provedores que recebem suporte do Firebase Authentication, a Microsoft não fornece um URL de foto. Em vez disso, os dados binários de uma foto de perfil precisam ser solicitados por meio da API Microsoft Graph.

    Além do token de acesso OAuth, é possível usar o objeto firebase.auth.UserCredential para recuperar o token de ID OAuth do usuário. A declaração sub no token de ID é específica do app e não vai corresponder ao identificador federado de usuários, que é usado pelo Firebase Auth e pode ser acessado utilizando user.providerData[0].uid. Nesse caso, o campo de declaração oid deve ser utilizado. Ao usar um locatário do Azure AD para fazer login, a declaração oid será uma correspondência exata. No entanto, para o caso sem locatário, o campo oid será preenchido. Para um ID federado 4b2eabcdefghijkl, oid terá um formulário 00000000-0000-0000-4b2e-abcdefghijkl.

  5. Os exemplos estão relacionados aos fluxos de login, mas também é possível vincular um provedor da Microsoft a um usuário atual com linkWithPopup/linkWithRedirect. Por exemplo, é possível vincular vários provedores ao mesmo usuário, o que permitirá que ele faça login usando qualquer um deles.

    WebWeb
    import { getAuth, linkWithPopup, OAuthProvider } from "firebase/auth";
    
    const provider = new OAuthProvider('microsoft.com');
    const auth = getAuth();
    
    linkWithPopup(auth.currentUser, provider)
        .then((result) => {
          // Microsoft credential is linked to the current user.
          // IdP data available in result.additionalUserInfo.profile.
    
          // Get the OAuth access token and ID Token
          const credential = OAuthProvider.credentialFromResult(result);
          const accessToken = credential.accessToken;
          const idToken = credential.idToken;
        })
        .catch((error) => {
          // Handle error.
        });
    var provider = new firebase.auth.OAuthProvider('microsoft.com');
    firebase.auth().currentUser.linkWithPopup(provider)
        .then((result) => {
          // Microsoft credential is linked to the current user.
          // IdP data available in result.additionalUserInfo.profile.
          // OAuth access token can also be retrieved:
          // result.credential.accessToken
          // OAuth ID token can also be retrieved:
          // result.credential.idToken
        })
        .catch((error) => {
          // Handle error.
        });
  6. É possível usar o mesmo padrão com reauthenticateWithPopup/reauthenticateWithRedirect, que pode ser utilizado para recuperar credenciais novas para operações confidenciais que exigem um login recente.

    WebWeb
    import { getAuth, reauthenticateWithPopup, OAuthProvider } from "firebase/auth";
    
    const provider = new OAuthProvider('microsoft.com');
    const auth = getAuth();
    reauthenticateWithPopup(auth.currentUser, provider)
        .then((result) => {
          // User is re-authenticated with fresh tokens minted and
          // should be able to perform sensitive operations like account
          // deletion and email or password update.
          // IdP data available in result.additionalUserInfo.profile.
    
          // Get the OAuth access token and ID Token
          const credential = OAuthProvider.credentialFromResult(result);
          const accessToken = credential.accessToken;
          const idToken = credential.idToken;
        })
        .catch((error) => {
          // Handle error.
        });
    var provider = new firebase.auth.OAuthProvider('microsoft.com');
    firebase.auth().currentUser.reauthenticateWithPopup(provider)
        .then((result) => {
          // User is re-authenticated with fresh tokens minted and
          // should be able to perform sensitive operations like account
          // deletion and email or password update.
          // IdP data available in result.additionalUserInfo.profile.
          // OAuth access token can also be retrieved:
          // result.credential.accessToken
          // OAuth ID token can also be retrieved:
          // result.credential.idToken
        })
        .catch((error) => {
          // Handle error.
        });

Se você ativou a configuração Uma conta por endereço de e-mail no Console do Firebase, quando um usuário tentar se conectar a um provedor (como a Microsoft) com um e-mail que já existe em outro provedor de usuário do Firebase (como o Google), o erro auth/account-exists-with-different-credential será exibido com um objeto AuthCredential (credencial da Microsoft). Para concluir o login no provedor pretendido, o usuário primeiro precisa fazer login no provedor atual (Google) e depois vinculá-lo ao AuthCredential anterior (credencial da Microsoft).

Se você usar signInWithPopup, poderá corrigir erros auth/account-exists-with-different-credential utilizando código, como o do exemplo a seguir:

import {
  getAuth,
  linkWithCredential,
  signInWithPopup,
  OAuthProvider,
} from "firebase/auth";

try {
  // Step 1: User tries to sign in using Microsoft.
  let result = await signInWithPopup(getAuth(), new OAuthProvider());
} catch (error) {
  // Step 2: User's email already exists.
  if (error.code === "auth/account-exists-with-different-credential") {
    // The pending Microsoft credential.
    let pendingCred = error.credential;

    // Step 3: Save the pending credential in temporary storage,

    // Step 4: Let the user know that they already have an account
    // but with a different provider, and let them choose another
    // sign-in method.
  }
}

// ...

try {
  // Step 5: Sign the user in using their chosen method.
  let result = await signInWithPopup(getAuth(), userSelectedProvider);

  // Step 6: Link to the Microsoft credential.
  // TODO: implement `retrievePendingCred` for your app.
  let pendingCred = retrievePendingCred();

  if (pendingCred !== null) {
    // As you have access to the pending credential, you can directly call the
    // link method.
    let user = await linkWithCredential(result.user, pendingCred);
  }

  // Step 7: Continue to app.
} catch (error) {
  // ...
}

Modo de redirecionamento

O processamento desse erro é similar no modo de redirecionamento. No entanto, nele, as credenciais pendentes devem ser armazenadas em cache entre os redirecionamentos de página usando, por exemplo, o armazenamento de sessão.

Ao contrário de outros provedores OAuth aceitos pelo Firebase, como Google, Facebook e Twitter, em que é possível fazer login diretamente com credenciais baseadas em token de acesso OAuth, isso não é possível no Firebase Auth ao usar provedores como a Microsoft porque o servidor do Firebase Auth não consegue verificar o público dos tokens de acesso OAuth da Microsoft. Esse é um requisito de segurança crítico e pode expor aplicativos e sites a ataques de repetição em que um token de acesso OAuth da Microsoft recebido em um projeto (invasor) pode ser usado para acessar outro projeto (vítima). Em vez disso, o Firebase Auth permite gerenciar todo o fluxo do OAuth e trocar o código de autorização usando o ID do cliente e o secret do OAuth configurados no Console do Firebase. Um código de autorização recebido em um projeto não pode ser usado em outro, porque só pode ser utilizado em conjunto com um ID do cliente/secret específicos.

Se for preciso usar esses provedores em ambientes sem suporte, será necessário usar uma biblioteca OAuth de terceiros e uma autenticação personalizada do Firebase. O primeiro é necessário para autenticar no provedor, e o segundo para trocar a credencial do provedor por um token personalizado.

Autenticar com Firebase em uma extensão do Chrome

Se você estiver criando um aplicativo de extensão do Google Chrome, consulte a Guia de documentos fora da tela.

O Firebase provisionará um subdomínio exclusivo para o projeto https://my-app-12345.firebaseapp.com no momento da criação dele.

Esse subdomínio também será usado como mecanismo de redirecionamento para o login do OAuth. Esse domínio precisaria ter permissão para todos os provedores OAuth com suporte. No entanto, isso significa que os usuários poderiam ver esse domínio ao fazer login na Microsoft antes do redirecionamento para o aplicativo: Continuar para: https://my-app-12345.firebaseapp.com.

Para evitar a exibição do subdomínio, configure um domínio personalizado com o Firebase Hosting:

  1. Siga as etapas de 1 a 3 em Configurar o domínio para o Hosting. Quando você verifica a propriedade do domínio, o Hosting provisiona um certificado SSL para o domínio personalizado.
  2. Adicione o domínio personalizado à lista de domínios autorizados no console Firebase: auth.custom.domain.com.
  3. No console para desenvolvedores da Microsoft ou na página de configuração do OAuth, adicione o URL da página de redirecionamento à lista de permissões, que estará acessível no seu domínio personalizado: https://auth.custom.domain.com/__/auth/handler.
  4. Ao inicializar a biblioteca JavaScript, especifique seu domínio personalizado com o campo authDomain:
    var config = {
      apiKey: '...',
      // Changed from 'PROJECT_ID.firebaseapp.com'.
      authDomain: 'auth.custom.domain.com',
      databaseURL: 'https://PROJECT_ID.firebaseio.com',
      projectId: 'PROJECT_ID',
      storageBucket: 'PROJECT_ID.firebasestorage.app',
      messagingSenderId: 'SENDER_ID'
    };
    firebase.initializeApp(config);

Próximas etapas

Depois que um usuário faz login pela primeira vez, uma nova conta de usuário é criada e vinculada às credenciais, que podem ser o número do telefone, o nome de usuário e a senha ou as informações do provedor de autenticação. Essa nova conta é armazenada como parte do projeto do Firebase e pode ser usada para identificar um usuário em todos os apps do projeto, seja qual for o método de login utilizado.

  • Nos apps, a maneira recomendada de saber o status de autenticação do seu usuário é definindo um observador no objeto Auth. É possível, então, receber as informações básicas de perfil do usuário do objeto User. Consulte Gerenciar usuários.

  • Nas Regras de segurança Firebase Realtime Database e Cloud Storage, você pode acessar o ID exclusivo do usuário conectado pela variável auth e usar essas informações para controlar quais dados um usuário pode acessar.

Os usuários podem fazer login no app usando vários provedores de autenticação. Basta vincular as credenciais desses provedores a uma conta de usuário.

Para desconectar um usuário, chame signOut:

WebWeb
import { getAuth, signOut } from "firebase/auth";

const auth = getAuth();
signOut(auth).then(() => {
  // Sign-out successful.
}).catch((error) => {
  // An error happened.
});
firebase.auth().signOut().then(() => {
  // Sign-out successful.
}).catch((error) => {
  // An error happened.
});