Como fazer login de usuários com OIDC

Este documento mostra como usar o Identity Platform para fazer login de usuários com um provedor OpenID Connect (OIDC).

Antes de começar

  1. Faça login na sua conta do Google Cloud. Se você começou a usar o Google Cloud agora, crie uma conta para avaliar o desempenho de nossos produtos em situações reais. Clientes novos também recebem US$ 300 em créditos para executar, testar e implantar cargas de trabalho.
  2. No console do Google Cloud, na página do seletor de projetos, selecione ou crie um projeto do Google Cloud.

    Acessar o seletor de projetos

  3. Verifique se a cobrança está ativada para o seu projeto do Google Cloud.

  4. No console do Google Cloud, na página do seletor de projetos, selecione ou crie um projeto do Google Cloud.

    Acessar o seletor de projetos

  5. Verifique se a cobrança está ativada para o seu projeto do Google Cloud.

  6. Ative o Identity Platform e adicione o SDK do cliente ao seu app. Consulte o Guia de início rápido para saber como fazer isso.

Como configurar o provedor

  1. Acesse a página Provedores de identidade no console do Google Cloud.
    Acessar a página "Provedores do Identity Platform"

  2. Clique em Adicionar um provedor e selecione OpenID Connect na lista.

Fluxo do código de autorização

  1. Insira os seguintes detalhes para ativar o fluxo de código de autorização:

    1. Selecione Fluxo de código na seção Escolher tipo de concessão.

    2. O Nome do provedor. Ele pode ser igual ao ID do provedor ou um nome personalizado. Se você inserir um nome personalizado, clique em Editar ao lado de ID do provedor para especificar o ID (que precisa começar com oidc.).

    3. O ID do cliente do provedor.

    4. O Emissor do provedor. A aparência será semalhente a esta: https://example.com. O Identity Platform usa esse URL para localizar o documento de descoberta OIDC (normalmente fica em /.well-known/openid-configuration) que especifica os endpoints OAuth e as chaves públicas do provedor.

    5. A chave secreta do cliente do provedor.

  2. Adicione seu app à lista de Domínios autorizados. Por exemplo, se o URL de login do seu aplicativo for https://example.com/login, adicione example.com.

  3. Configure o URL de callback do Identity Platform como um URL de redirecionamento com seu provedor OIDC. O URL precisa ser semelhante a https://[PROJECT-ID].firebaseapp.com/__/auth/handler.

  4. Clique em Salvar.

Fluxo implícito

  1. Insira os seguintes detalhes para ativar o fluxo implícito:

    1. Selecione Fluxo implícito na seção Escolher tipo de concessão.

    2. O Nome do provedor. Ele pode ser igual ao ID do provedor ou um nome personalizado. Se você inserir um nome personalizado, clique em Editar ao lado de ID do provedor para especificar o ID (que precisa começar com oidc.).

    3. O ID do cliente do provedor.

    4. O Emissor do provedor. Isso precisa ser parecido como https://example.com.. O Identity Platform usa esse URL para localizar o documento de descoberta do OIDC, normalmente encontrado em /.well-known/openid-configuration, que especifica os endpoints OAuth do provedor e as chaves públicas.

  2. Adicione seu app à lista de Domínios autorizados. Por exemplo, se o URL de login do seu aplicativo for https://example.com/login, adicione example.com.

  3. Configure o URL de callback do Identity Platform como um URL de redirecionamento com seu provedor OIDC. O URL precisa ser semelhante a https://[PROJECT-ID].firebaseapp.com/__/auth/handler.

  4. Clique em Salvar.

Como conectar usuários

Há duas maneiras de fazer login dos usuários com o OIDC:

  • Usando fluxo de OAuth. Essa abordagem conclui o handshake do OAuth para você. Com base na seleção de fluxo de código de autorização/fluxo implícito na etapa da configuração do provedor, o servidor GCIP escolhe o fluxo desejado para se comunicar com o provedor de identidade.

  • Usar o token de ID do provedor OIDC. Esse método presume que você já tem um token OIDC disponível.

Como fazer login dos usuários com o OAuth

Para fazer login usando o OAuth:

  1. Crie uma instância OAuthProvider com o ID do provedor configurado na seção anterior. O ID do provedor precisa começar com oidc..

    Versão 9 para a Web

    import { OAuthProvider } from "firebase/auth";
    
    const provider = new OAuthProvider("oidc.myProvider");

    Versão 8 para a Web

    const provider = new firebase.auth.OAuthProvider('oidc.myProvider');
  2. Inicie o fluxo de login. É possível usar um pop-up ou um redirecionamento.

    Versão 9 para a Web

    import { getAuth, signInWithPopup, OAuthProvider } from "firebase/auth";
    
    const auth = getAuth();
    signInWithPopup(auth, provider)
      .then((result) => {
        // User is signed in.
        const credential = OAuthProvider.credentialFromResult(result);
        // This gives you an access token for the OIDC provider. You can use it to directly interact with that provider
      }).catch((error) => {
        // Handle Errors here.
        const errorCode = error.code;
        const errorMessage = error.message;
        // The email of the user's account used.
        const email = error.customData.email;
        // The AuthCredential type that was used.
        const credential = OAuthProvider.credentialFromError(error);
        // Handle / display error.
        // ...
      });

    Versão 8 para a Web

    firebase.auth().signInWithPopup(provider)
      .then((result) => {
        // User is signed in.
        // result.credential is a firebase.auth().OAuthCredential object.
        // result.credential.providerId is equal to 'oidc.myProvider'.
        // result.credential.idToken is the OIDC provider's ID token.
      })
      .catch((error) => {
        // Handle error.
      });

    Redirecionamento

    Para redirecionar a uma página de login, chame signInWithRedirect():

    Versão 9 para a Web

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

    Versão 8 para a Web

    firebase.auth().signInWithRedirect(provider).catch((error) => {
      // Handle error.
    });

    Em seguida, chame getRedirectResult() para receber os resultados quando o usuário retornar ao app:

    Versão 9 para a Web

    import { getAuth, getRedirectResult, OAuthProvider } from "firebase/auth";
    
    const auth = getAuth();
    getRedirectResult(auth)
      .then((result) => {
        // User is signed in.
        const credential = OAuthProvider.credentialFromResult(result);
        // This gives you an access token for the OIDC provider. You can use it to directly interact with that provider
      })
      .catch((error) => {
        // Handle Errors here.
        const errorCode = error.code;
        const errorMessage = error.message;
        // The email of the user's account used.
        const email = error.customData.email;
        // The AuthCredential type that was used.
        const credential = OAuthProvider.credentialFromError(error);
        // Handle / display error.
        // ...
      });

    Versão 8 para a Web

    // On return.
    firebase.auth().getRedirectResult()
      .then((result) => {
        // User is signed in.
        // result.credential is a firebase.auth().OAuthCredential object.
        // result.credential.providerId is equal to 'oidc.myProvider'.
        // result.credential.idToken is the OIDC provider's ID token.
      })
      .catch((error) => {
        // Handle / display error.
        // ...
      });

Ao concluir um dos fluxos, é possível conseguir o token de ID do OIDC usando o campo result.credential.idToken.

Como fazer login de usuários diretamente

Para fazer o login de um usuário com um token de ID OIDC diretamente, faça o seguinte:

  1. Inicialize uma instância do OAuthProvider com o ID do provedor que você configurou na seção anterior. O ID do provedor precisa começar com oidc.. Em seguida, crie uma OAuthCredential e chame signInWithCredential() para fazer o login do usuário.

    Versão 9 para a Web

    import { getAuth, OAuthProvider, signInWithCredential } from "firebase/auth";
    
    const auth = getAuth();
    const credential = provider.credential({
      idToken: oidcIdToken,
    });
    signInWithCredential(auth, credential)
      .then((result) => {
        // User is signed in.
        const newCredential = OAuthProvider.credentialFromResult(result);
        // This gives you a new access token for the OIDC provider. You can use it to directly interact with that provider.
      })
      .catch((error) => {
        // Handle Errors here.
        const errorCode = error.code;
        const errorMessage = error.message;
        // The email of the user's account used.
        const email = error.customData.email;
        // The AuthCredential type that was used.
        const credential = OAuthProvider.credentialFromError(error);
        // Handle / display error.
        // ...
      });

    Versão 8 para a Web

    const credential = provider.credential(oidcIdToken, null);
    
    firebase.auth().signInWithCredential(credential)
      .then((result) => {
        // User is signed in.
        // User now has a odic.myProvider UserInfo in providerData.
      })
      .catch((error) => {
        // Handle / display error.
        // ...
      });

Como vincular contas de usuário

Se um usuário já tiver feito login no seu app usando um método diferente (como e-mail/senha), será possível vincular a conta atual ao provedor OIDC usando linkWithPopup() ou linkWithRedirect(): Por exemplo, podemos vincular a uma Conta do Google:

Versão 9 para a Web

import { getAuth, linkWithPopup, GoogleAuthProvider } from "firebase/auth";
const provider = new GoogleAuthProvider();

const auth = getAuth();
linkWithPopup(auth.currentUser, provider).then((result) => {
  // Accounts successfully linked.
  const credential = GoogleAuthProvider.credentialFromResult(result);
  const user = result.user;
  // ...
}).catch((error) => {
  // Handle Errors here.
  // ...
});

Versão 8 para a Web

auth.currentUser.linkWithPopup(provider).then((result) => {
  // Accounts successfully linked.
  var credential = result.credential;
  var user = result.user;
  // ...
}).catch((error) => {
  // Handle Errors here.
  // ...
});

A seguir