Guia para desenvolvedores sobre a API Federated Credential Management

Saiba como usar o FedCM para preservar a privacidade na federação de identidade.

O FedCM (gerenciamento de credenciais federadas) é uma abordagem que preserva a privacidade em serviços de identidade federada (como "Fazer login com..."), em que os usuários podem fazer login em sites sem compartilhar informações pessoais com o serviço de identidade ou com o site.

Para saber mais sobre casos de uso, fluxos de usuários e o roadmap da API, consulte a introdução à API FedCM.

Ambiente de desenvolvimento do FedCM

Você precisa de um contexto seguro (HTTPS ou localhost) no IdP e no RP no Chrome para usar o FedCM.

Depurar código no Chrome para Android

Configure e execute um servidor localmente para depurar o código do FedCM. É possível acessar esse servidor no Chrome em um dispositivo Android conectado por um cabo USB com encaminhamento de portas.

É possível usar o DevTools no computador para depurar o Chrome no Android seguindo as instruções em Depuração remota de dispositivos Android.

Bloquear cookies de terceiros no Chrome

Simular a descontinuação gradual de cookies de terceiros configurando o Chrome para bloqueá-los
Simule a descontinuação de cookies de terceiros configurando o Chrome para bloqueá-los

Você pode testar como o FedCM funciona sem cookies de terceiros no Chrome antes que ele seja realmente aplicado.

Para bloquear cookies de terceiros, use o modo de navegação anônima ou escolha "Bloquear cookies de terceiros" nas configurações do computador em chrome://settings/cookies ou no dispositivo móvel, acessando Configurações > Configurações do site > Cookies.

Como usar a API FedCM

Você integra com o FedCM criando um arquivo conhecido, arquivo de configuração e endpoints para lista de contas, emissão de declarações e, opcionalmente, metadados do cliente.

A partir daí, o FedCM expõe APIs JavaScript que os RPs podem usar para fazer login com o IdP.

Criar um arquivo conhecido

Para evitar que os rastreadores abusem da API, um arquivo conhecido precisa ser enviado do /.well-known/web-identity do eTLD+1 do IdP.

Por exemplo, se os endpoints do IdP forem veiculados em https://accounts.idp.example/, eles precisarão veicular um arquivo conhecido em https://idp.example/.well-known/web-identity, além de um arquivo de configuração do IdP. Confira um exemplo de conteúdo de arquivo conhecido:

{
  "provider_urls": ["https://accounts.idp.example/config.json"]
}

O arquivo JSON precisa conter a propriedade provider_urls com uma matriz de URLs de arquivo de configuração do IdP que podem ser especificados como parte do caminho de configURL em navigator.credentials.get pelos RPs. O número de strings de URL na matriz é limitado a um, mas isso pode mudar com seu feedback no futuro.

Criar um arquivo de configuração do IdP e endpoints

O arquivo de configuração do IdP fornece uma lista de endpoints necessários para o navegador. As IdPs hospedarão esse arquivo de configuração e os endpoints e URLs necessários. Todas as respostas JSON precisam ser enviadas com o tipo de conteúdo application/json.

O URL do arquivo de configuração é determinado pelos valores fornecidos para a chamada navigator.credentials.get executada em um RP.

const credential = await navigator.credentials.get({
  identity: {
    context: 'signup',
    providers: [{
      configURL: 'https://accounts.idp.example/config.json',
      clientId: '********',
      nonce: '******'
    }]
  }
});
const { token } = credential;

Especifique um URL completo do local do arquivo de configuração do IdP como um configURL. Quando navigator.credentials.get() é chamado no RP, o navegador busca o arquivo de configuração com uma solicitação GET sem o cabeçalho Origin ou Referer. A solicitação não tem cookies e não segue redirecionamentos. Isso efetivamente impede que o IdP saiba quem fez a solicitação e qual RP está tentando se conectar. Exemplo:

GET /config.json HTTP/1.1
Host: accounts.idp.example
Accept: application/json
Sec-Fetch-Dest: webidentity

O navegador espera uma resposta JSON do IdP que inclui as seguintes propriedades:

Propriedade Descrição
accounts_endpoint (obrigatório) URL do endpoint das contas.
client_metadata_endpoint (opcional) URL do endpoint de metadados do cliente.
id_assertion_endpoint (obrigatório) URL do endpoint de declaração de ID.
disconnect (opcional) URL do endpoint de desconexão.
login_url (obrigatório) O URL da página de login para o usuário fazer login no IdP.
branding (opcional) Objeto que contém várias opções de marca.
branding.background_color (opcional) Opção de marca que define a cor de plano de fundo do botão "Continuar como...". Use a sintaxe CSS relevante, ou seja, hex-color, hsl(), rgb() ou named-color.
branding.color (opcional) Opção de marca que define a cor do texto do botão "Continuar como...". Use a sintaxe CSS relevante, ou seja, hex-color, hsl(), rgb() ou named-color.
branding.icons (opcional) Opção de branding que define o objeto do ícone, exibido na caixa de diálogo de login. O objeto de ícone é uma matriz com dois parâmetros:
  • url (obrigatório): URL da imagem do ícone. Ele não oferece suporte a imagens SVG.
  • size (opcional): dimensões do ícone, presumidas pelo aplicativo como quadradas e de resolução única. Esse número precisa ser maior ou igual a 25.

A RP pode modificar a string na interface do diálogo FedCM usando o valor identity.context para navigator.credentials.get() para acomodar contextos de autenticação predefinidos. A propriedade opcional pode ser "signin" (padrão), "signup", "use" ou "continue".

Como o branding é aplicado à caixa de diálogo FedCM
Como a marca é aplicada à caixa de diálogo FedCM

Confira um exemplo de corpo de resposta do IdP:

{
  "accounts_endpoint": "/accounts.php",
  "client_metadata_endpoint": "/client_metadata.php",
  "id_assertion_endpoint": "/assertion.php",
  "disconnect_endpoint": "/disconnect.php",
  "login_url": "/login",
  "branding": {
    "background_color": "green",
    "color": "#FFEEAA",
    "icons": [{
      "url": "https://idp.example/icon.ico",
      "size": 25
    }]
  }
}

Depois que o navegador recupera o arquivo de configuração, ele envia solicitações subsequentes para os endpoints do IdP:

Endpoints do IdP
Endpoints do provedor de identidade

Endpoint de contas

O endpoint de contas do IdP retorna uma lista de contas em que o usuário está conectado no IdP. Se o IdP oferecer suporte a várias contas, esse endpoint vai retornar todas as contas que fizeram login.

O navegador envia uma solicitação GET com cookies com SameSite=None, mas sem um parâmetro client_id, o cabeçalho Origin ou o cabeçalho Referer. Isso impede que o IdP saiba em qual RP o usuário está tentando fazer login. Exemplo:

GET /accounts.php HTTP/1.1
Host: accounts.idp.example
Accept: application/json
Cookie: 0x23223
Sec-Fetch-Dest: webidentity

Ao receber a solicitação, o servidor precisa:

  1. Verifique se a solicitação contém um cabeçalho HTTP Sec-Fetch-Dest: webidentity.
  2. Correlacione os cookies de sessão aos IDs das contas já conectadas.
  3. Responda com a lista de contas.

O navegador espera uma resposta JSON que inclua uma propriedade accounts com uma matriz de informações de conta com as seguintes propriedades:

Propriedade Descrição
id (obrigatório) ID exclusivo do usuário.
name (obrigatório) Nome e sobrenome do usuário.
email (obrigatório) Endereço de e-mail do usuário.
given_name (opcional) Nome do usuário.
picture (opcional) URL da imagem do avatar do usuário.
approved_clients (opcional) Uma matriz de IDs de cliente de RP com que o usuário se registrou.
login_hints (opcional) Uma matriz de todos os tipos de filtro possíveis que o IdP aceita para especificar uma conta. A RP pode invocar navigator.credentials.get() com a propriedade loginHint para exibir seletivamente a conta especificada.
domain_hints (opcional) Uma matriz de todos os domínios aos quais a conta está associada. O RP pode chamar navigator.credentials.get() com uma propriedade domainHint para filtrar as contas.

Exemplo de corpo de resposta:

{
  "accounts": [{
    "id": "1234",
    "given_name": "John",
    "name": "John Doe",
    "email": "john_doe@idp.example",
    "picture": "https://idp.example/profile/123",
    "approved_clients": ["123", "456", "789"],
    "login_hints": ["demo1", "demo1@idp.example"]
  }, {
    "id": "5678",
    "given_name": "Johnny",
    "name": "Johnny",
    "email": "johnny@idp.example",
    "picture": "https://idp.example/profile/456",
    "approved_clients": ["abc", "def", "ghi"],
    "login_hints": ["demo2", "demo2@idp.example"],
    "domain_hints": ["corp.example"]
  }]
}

Se o usuário não estiver conectado, responda com HTTP 401 (Não autorizado).

A lista de contas retornada é consumida pelo navegador e não estará disponível para o RP.

Endpoint de metadados do cliente

O endpoint de metadados do cliente do provedor de identidade retorna os metadados da parte confiável, como a política de privacidade e os termos de serviço da parte confiável. Os RPs precisam fornecer links para a Política de Privacidade e os Termos de Serviço ao IdP com antecedência. Esses links são exibidos na caixa de diálogo de login quando o usuário ainda não se registrou na RP com o IdP.

O navegador envia uma solicitação GET usando o client_id navigator.credentials.get sem cookies. Exemplo:

GET /client_metadata.php?client_id=1234 HTTP/1.1
Host: accounts.idp.example
Origin: https://rp.example/
Accept: application/json
Sec-Fetch-Dest: webidentity

Ao receber a solicitação, o servidor deve:

  1. Determine o RP para o client_id.
  2. Responda com os metadados do cliente.

As propriedades do endpoint de metadados do cliente incluem:

Propriedade Descrição
privacy_policy_url (opcional) URL da Política de Privacidade do RP.
terms_of_service_url (opcional) URL dos Termos de Serviço do RP.

O navegador espera uma resposta JSON do endpoint:

{
  "privacy_policy_url": "https://rp.example/privacy_policy.html",
  "terms_of_service_url": "https://rp.example/terms_of_service.html",
}

Os metadados do cliente retornados são consumidos pelo navegador e não ficam disponíveis para a RP.

Endpoint de declaração de ID

O endpoint de declaração de ID do IdP retorna uma declaração para o usuário conectado. Quando o usuário faz login em um site de RP usando a chamada navigator.credentials.get(), o navegador envia uma solicitação POST com cookies com SameSite=None e um tipo de conteúdo application/x-www-form-urlencoded para esse endpoint com as seguintes informações:

Propriedade Descrição
client_id (obrigatório) O identificador de cliente do RP.
account_id (obrigatório) O ID exclusivo do usuário que fez login.
nonce (opcional) O valor de uso único da solicitação, fornecido pela parte restrita.
disclosure_text_shown Resulta em uma string de "true" ou "false" (em vez de um booleano). O resultado é "false" se o texto de divulgação não foi mostrado. Isso acontece quando o ID do cliente da parte restrita foi incluído na lista de propriedades approved_clients da resposta do endpoint de contas ou se o navegador observou um momento de inscrição no passado na ausência de approved_clients.
is_auto_selected Se a reautenticação automática for realizada na parte restrita, is_auto_selected vai indicar "true". Caso contrário, "false". Isso é útil para oferecer suporte a mais recursos relacionados à segurança. Por exemplo, alguns usuários podem preferir um nível de segurança mais alto, que exige a mediação explícita do usuário na autenticação. Se um IdP receber uma solicitação de token sem essa mediação, ele poderá processar a solicitação de maneira diferente. Por exemplo, retorne um código de erro para que o RP possa chamar a API FedCM novamente com mediation: required.

Exemplo de cabeçalho HTTP:

POST /assertion.php HTTP/1.1
Host: accounts.idp.example
Origin: https://rp.example/
Content-Type: application/x-www-form-urlencoded
Cookie: 0x23223
Sec-Fetch-Dest: webidentity

account_id=123&client_id=client1234&nonce=Ct60bD&disclosure_text_shown=true&is_auto_selected=true

Ao receber a solicitação, o servidor deve:

  1. Responda à solicitação com o Compartilhamento de recursos entre origens (CORS, na sigla em inglês).
  2. Verifique se a solicitação contém um cabeçalho HTTP Sec-Fetch-Dest: webidentity.
  3. Correlacione o cabeçalho Origin à origem do RP determinada pelo client_id. Rejeite se não forem correspondentes.
  4. Corresponda account_id ao ID da conta já conectada. Rejeite se não corresponderem.
  5. Responda com um token. Se a solicitação for rejeitada, responda com uma resposta de erro.

A forma como o token é emitido é de responsabilidade do IdP, mas, em geral, ele é assinado com informações como o ID da conta, o ID do cliente, a origem do emissor e nonce, para que a RP possa verificar se o token é genuíno.

O navegador espera uma resposta JSON que inclua a seguinte propriedade:

Propriedade Descrição
token (obrigatório) Um token é uma string que contém declarações sobre a autenticação.
{
  "token": "***********"
}

O token retornado é transmitido à RP pelo navegador para que a RP possa validar a autenticação.

Retornar uma resposta de erro

O id_assertion_endpoint também pode retornar uma resposta de "erro", que tem dois campos opcionais:

  • code: o IdP pode escolher um dos erros conhecidos da lista de erros especificados do OAuth 2.0 (invalid_request, unauthorized_client, access_denied, server_error e temporarily_unavailable) ou usar qualquer string arbitrária. Se for o último caso, o Chrome renderizará a interface do erro com uma mensagem de erro genérica e transmitirá o código para o RP.
  • url: identifica uma página da Web legível por humanos com informações sobre o erro para fornecer mais informações aos usuários. Esse campo é útil para os usuários porque os navegadores não podem fornecer mensagens de erro avançadas em uma interface nativa. Por exemplo, links para as próximas etapas, informações de contato do atendimento ao cliente e assim por diante. Se um usuário quiser saber mais sobre os detalhes do erro e como corrigi-lo, ele poderá visitar a página fornecida na interface do navegador para mais detalhes. O URL precisa ser do mesmo site que o IdP configURL.
// id_assertion_endpoint response
{
  "error" : {
     "code": "access_denied",
     "url" : "https://idp.example/error?type=access_denied"
  }
}

Desconectar endpoint

Ao invocar IdentityCredential.disconnect(), o navegador envia uma solicitação POST entre origens com cookies com SameSite=None e um tipo de conteúdo de application/x-www-form-urlencoded para esse endpoint de desconexão com as seguintes informações:

Propriedade Descrição
account_hint Uma dica para a conta do IdP.
client_id O identificador de cliente do RP.
POST /disconnect.php HTTP/1.1
Host: idp.example
Origin: rp.example
Content-Type: application/x-www-form-urlencoded
Cookie: 0x123
Sec-Fetch-Dest: webidentity

account_hint=account456&client_id=rp123

Ao receber a solicitação, o servidor precisa:

  1. Responda à solicitação com o CORS (Compartilhamento de recursos entre origens).
  2. Verifique se a solicitação contém um cabeçalho HTTP Sec-Fetch-Dest: webidentity.
  3. Correlacione o cabeçalho Origin à origem do RP determinada pelo client_id. Rejeite se não forem correspondentes.
  4. Compare account_hint com os IDs das contas já conectadas.
  5. Desconecte a conta do usuário do RP.
  6. Responda ao navegador com as informações da conta de usuário identificada em formato JSON.

Um exemplo de payload JSON de resposta é parecido com este:

{
  "account_id": "account456"
}

Em vez disso, se o IdP quiser que o navegador desconecte todas as contas associadas à RP, transmita uma string que não corresponda a nenhum ID da conta, por exemplo, "*".

URL de login

Com a API Login Status, o IdP precisa informar o status de login do usuário ao navegador. No entanto, o status pode estar desincronizado, por exemplo, quando a sessão expira. Nesse cenário, o navegador pode permitir que o usuário faça login no IdP dinamicamente pelo URL da página de login especificado com o login_url do arquivo de configuração do IdP.

A caixa de diálogo do FedCM mostra uma mensagem sugerindo um login, como mostrado na imagem a seguir.

A
Uma caixa de diálogo do FedCM sugerindo o login no IdP.

Quando o usuário clica no botão Continuar, o navegador abre uma janela pop-up para a página de login do IdP.

Exemplo de caixa de diálogo do FedCM.
Exemplo de caixa de diálogo mostrada após clicar no botão de login no IdP.

A caixa de diálogo é uma janela de navegador normal com cookies primários. O que acontecer na caixa de diálogo cabe ao IdP, e nenhum identificador de janela está disponível para fazer uma solicitação de comunicação de origem cruzada para a página da RP. Depois que o usuário fizer login, o IdP precisará:

  • Envie o cabeçalho Set-Login: logged-in ou chame a API navigator.login.setStatus("logged-in") para informar ao navegador que o usuário fez login.
  • Chame IdentityProvider.close() para fechar a caixa de diálogo.
Um usuário faz login em um RP depois de fazer login no IdP usando o FedCM.

Informar o navegador sobre o status de login do usuário no provedor de identidade

A API Login Status é um mecanismo em que um site, especialmente um provedor de identidade, informa ao navegador o status de login do usuário no provedor. Com essa API, o navegador pode reduzir solicitações desnecessárias ao IdP e mitigar possíveis ataques de tempo.

Os IdPs podem sinalizar o status de login do usuário para o navegador enviando um cabeçalho HTTP ou chamando uma API JavaScript quando o usuário faz login no IdP ou quando ele faz logout de todas as contas do IdP. Para cada IdP (identificado pelo URL de configuração), o navegador mantém uma variável de três estados que representa o estado de login com os valores possíveis logged-in, logged-out e unknown. O estado padrão é unknown.

Para indicar que o usuário fez login, envie um cabeçalho HTTP Set-Login: logged-in em uma navegação de alto nível ou uma solicitação de subrecurso no mesmo site na origem do IDP:

Set-Login: logged-in

Como alternativa, chame a API JavaScript navigator.login.setStatus("logged-in") da origem do IdP em uma navegação de nível superior:

navigator.login.setStatus("logged-in")

Essas chamadas registram o status de login do usuário como logged-in. Quando o status de login do usuário está definido como logged-in, o RP que chama o FedCM faz solicitações para o endpoint de contas do provedor de identidade e exibe as contas disponíveis para o usuário na caixa de diálogo do FedCM.

Para indicar que o usuário saiu de todas as contas, envie o cabeçalho HTTP Set-Login: logged-out em uma navegação de nível superior ou uma solicitação de subrecurso no mesmo site na origem do IdP:

Set-Login: logged-out

Como alternativa, chame a API JavaScript navigator.login.setStatus("logged-out") da origem do IdP em uma navegação de nível superior:

navigator.login.setStatus("logged-out")

Essas chamadas registram o status de login do usuário como logged-out. Quando o status de login do usuário for logged-out, chamar o FedCM falhará silenciosamente sem fazer uma solicitação ao endpoint de contas do IdP.

O status unknown é definido antes que o IdP envie um sinal usando a API Login Status. Unknown foi introduzido para uma transição melhor, porque um usuário pode já ter feito login no IdP quando essa API foi enviada. O IdP pode não ter a chance de sinalizar isso para o navegador até que o FedCM seja invocado pela primeira vez. Nesse caso, o Chrome faz uma solicitação para o endpoint de contas do IdP e atualiza o status com base na resposta do endpoint de contas:

  • Se o endpoint retornar uma lista de contas ativas, atualize o status para logged-in e abra a caixa de diálogo do FedCM para mostrar essas contas.
  • Se o endpoint não retornar contas, atualize o status para logged-out e falhe na chamada do FedCM.

Permitir que o usuário faça login por um fluxo dinâmico

Embora o IdP continue informando o status de login do usuário ao navegador, ele pode estar fora de sincronia, como quando a sessão expira. O navegador tenta enviar uma solicitação com credenciais para o endpoint de contas quando o status de login é logged-in, mas o servidor não retorna nenhuma conta porque a sessão não está mais disponível. Nesse cenário, o navegador pode permitir que o usuário faça login no IdP dinamicamente por uma janela pop-up.

Fazer login na parte confiável com o provedor de identidade

Quando a configuração e os endpoints do IdP estiverem disponíveis, os RPs poderão chamar navigator.credentials.get() para permitir que os usuários façam login no RP com o IdP.

Antes de chamar a API, você precisa confirmar se o [FedCM está disponível no navegador do usuário]. Para verificar se o FedCM está disponível, use este código na sua implementação do FedCM:

if ('IdentityCredential' in window) {
  // If the feature is available, take action
}

Para permitir que os usuários façam login no IdP pelo RP, faça o seguinte:

const credential = await navigator.credentials.get({
  identity: {
    providers: [{
      configURL: 'https://accounts.idp.example/config.json',
      clientId: '********',
      nonce: '******'
    }]
  }
});
const { token } = credential;

A propriedade providers usa uma matriz de objetos IdentityProvider com as seguintes propriedades:

Propriedade Descrição
configURL (obrigatório) Um caminho completo do arquivo de configuração do IdP.
clientId (obrigatório) O identificador do cliente da RP, emitido pelo IdP.
nonce (opcional) Uma string aleatória para garantir que a resposta seja emitida para essa solicitação específica. Evita ataques de repetição.
loginHint (opcional) Ao especificar um dos valores login_hints fornecidos pelos endpoints de contas, a caixa de diálogo FedCM mostra seletivamente a conta especificada.
domainHint (opcional) Ao especificar um dos valores domain_hints fornecidos pelos endpoints de contas, a caixa de diálogo FedCM mostra seletivamente a conta especificada.

O navegador processa os casos de uso de inscrição e login de maneira diferente, dependendo da existência de approved_clients na resposta do endpoint da lista de contas. O navegador não vai mostrar um texto de revelação "Para continuar com ...." se o usuário já tiver se inscrito no RP.

O estado de inscrição é determinado com base no atendimento ou não das seguintes condições:

  • Se approved_clients incluir o clientId do RP.
  • Se o navegador lembrar que o usuário já se inscreveu no RP.
Um usuário faz login em um RP usando o FedCM.

Quando o RP chama navigator.credentials.get(), as seguintes atividades acontecem:

  1. O navegador envia solicitações e recupera vários documentos:
    1. O arquivo conhecido e um arquivo de configuração do IdP que declara endpoints.
    2. Uma lista de contas.
    3. Opcional: URLs para a Política de Privacidade e os Termos de Serviço da RP, recuperados do endpoint de metadados do cliente.
  2. O navegador mostra a lista de contas que o usuário pode usar para fazer login, bem como os Termos de Serviço e a Política de Privacidade, se disponíveis.
  3. Depois que o usuário escolhe uma conta para fazer login, uma solicitação para o endpoint de declaração de ID é enviada ao IdP para recuperar um token.
  4. O RP pode validar o token para autenticar o usuário.
Chamada de API de login
login API call

Espera-se que os RPs ofereçam suporte a navegadores que não oferecem suporte ao FedCM. Portanto, os usuários poderão usar um processo de login que não seja do FedCM. Até que os cookies de terceiros sejam totalmente desativados, isso não será um problema.

Depois que o token é validado pelo servidor da RP, a RP pode registrar o usuário ou deixá-lo fazer login e iniciar uma nova sessão.

API Login Hint

Depois que o usuário faz login, às vezes a parte confiável (RP) pede para o usuário autenticar novamente. Mas o usuário pode não ter certeza de qual conta está usando. Se o RP puder especificar com qual conta fazer login, será mais fácil para o usuário escolher uma conta.

Os RPs podem mostrar seletivamente uma conta específica invocando navigator.credentials.get() com a propriedade loginHint com um dos valores login_hints buscados do endpoint da lista de contas, conforme mostrado no seguinte exemplo de código:

return await navigator.credentials.get({
  identity: {
    providers: [{
      configURL: "https://idp.example/manifest.json",
      clientId: "123",
      nonce: nonce,
      loginHint : "demo1@example.com"
    }]
  }
});

Quando nenhuma conta corresponde ao loginHint, a caixa de diálogo FedCM mostra um prompt de login, que permite que o usuário faça login em uma conta do IdP que corresponde à dica solicitada pelo RP. Quando o usuário toca no comando, uma janela pop-up é aberta com o URL de login especificado no arquivo de configuração. Em seguida, o link é anexado com a dica de login e os parâmetros de consulta de dica de domínio.

API Domain Hint

Há casos em que a parte restrita já sabe que apenas contas associadas a um determinado domínio têm permissão para fazer login no site. Isso é particularmente comum em cenários corporativos em que o site acessado é restrito a um domínio corporativo. Para oferecer uma melhor experiência do usuário, a API FedCM permite que o RP mostre apenas as contas que podem ser usadas para fazer login na RP. Isso evita cenários em que um usuário tenta fazer login no RP usando uma conta fora do domínio corporativo, apenas para receber uma mensagem de erro mais tarde (ou silêncio, quando o login não funciona) porque o tipo certo de conta não foi usado.

Os RPs podem mostrar seletivamente apenas as contas correspondentes invocando navigator.credentials.get() com a propriedade domainHint com um dos valores domain_hints buscados do endpoint da lista de contas, conforme mostrado no exemplo de código abaixo:

return await navigator.credentials.get({
  identity: {
    providers: [{
      configURL: "https://idp.example/manifest.json",
      clientId: "abc",
      nonce: nonce,
      domainHint : "corp.example"
    }]
  }
});

Quando nenhuma conta corresponde ao domainHint, a caixa de diálogo FedCM mostra um prompt de login, que permite que o usuário faça login em uma conta do IdP que corresponde à dica solicitada pelo RP. Quando o usuário toca no comando, uma janela pop-up é aberta com o URL de login especificado no arquivo de configuração. O link é anexado com a dica de login e os parâmetros de consulta de dica de domínio.

Exemplo de solicitação de login quando nenhuma conta corresponde a "domainHint".
Exemplo de solicitação de login quando nenhuma conta corresponde ao domainHint.

Mostrar uma mensagem de erro

Às vezes, o IdP não pode emitir um token por motivos legítimos, como quando o cliente não está autorizado ou o servidor está temporariamente indisponível. Se o IdP retornar uma resposta "erro", o RP poderá detectá-la, e o Chrome notificará o usuário mostrando uma interface do navegador com as informações de erro fornecidas pelo IdP.

A
Uma caixa de diálogo do FedCM mostrando a mensagem de erro após a tentativa de login do usuário falhar. A string é associada ao tipo de erro.
try {
  const cred = await navigator.credentials.get({
    identity: {
      providers: [
        {
          configURL: "https://idp.example/manifest.json",
          clientId: "1234",
        },
      ],
    }
  });
} catch (e) {
  const code = e.code;
  const url = e.url;
}

Refazer a autenticação dos usuários automaticamente após a autenticação inicial

A reautenticação automática do FedCM (abreviação de "auto-reautenticação" em inglês) permite que os usuários se reautentiquem automaticamente quando voltam após a autenticação inicial usando o FedCM. "A autenticação inicial" aqui significa que o usuário cria uma conta ou faz login no site da RP ao tocar no botão Continuar como... na caixa de diálogo de login do FedCM pela primeira vez na mesma instância do navegador.

Embora a experiência explícita do usuário faça sentido antes que o usuário tenha criado a conta federada para evitar o rastreamento (que é uma das principais metas do FedCM), ela é desnecessária depois que o usuário passou por ela uma vez: depois que o usuário concede permissão para permitir a comunicação entre o RP e o IdP, não há benefício de privacidade ou segurança para aplicar outra confirmação explícita do usuário para algo que ele já tenha reconhecido anteriormente.

Com a reautorização automática, o navegador muda o comportamento dependendo da opção especificada para o mediation ao chamar navigator.credentials.get().

const cred = await navigator.credentials.get({
  identity: {
    providers: [{
      configURL: "https://idp.example/fedcm.json",
      clientId: "1234",
    }],
  },
  mediation: 'optional', // this is the default
});

// `isAutoSelected` is `true` if auto-reauthn was performed.
const isAutoSelected = cred.isAutoSelected;

O mediation é uma propriedade na API Credential Management. Ele se comporta da mesma forma que o PasswordCredential e o FederatedCredential. Ele também tem suporte parcial do PublicKeyCredential. A propriedade aceita os quatro valores a seguir:

  • 'optional' (padrão): reautorização automática, se possível, ou requer mediação, se não for. Recomendamos escolher essa opção na página de login.
  • 'required': sempre requer uma mediação para continuar, por exemplo, clicando no botão "Continuar" na interface. Escolha essa opção se os usuários precisarem conceder a permissão explicitamente sempre que precisarem ser autenticados.
  • 'silent': reautorização automática, se possível, ou falha silenciosa sem exigir uma mediação, se não for possível. Recomendamos escolher essa opção nas páginas que não são de login, mas em que você quer manter os usuários conectados, como uma página de item em um site de frete ou uma página de artigo em um site de notícias.
  • 'conditional': usado para WebAuthn e não está disponível para FedCM no momento.

Com essa chamada, a reautorização automática ocorre nas seguintes condições:

  • O FedCM está disponível para uso. Por exemplo, o usuário não desativou o FedCM globalmente nem para a RP nas configurações.
  • O usuário usou apenas uma conta com a API FedCM para fazer login no site nesse navegador.
  • O usuário fez login no IdP com essa conta.
  • A reautenticação automática não aconteceu nos últimos 10 minutos.
  • O RP não chamou navigator.credentials.preventSilentAccess() após o login anterior.

Quando essas condições são atendidas, uma tentativa de reautenticar automaticamente o usuário começa assim que o navigator.credentials.get() do FedCM é invocado.

Quando mediation: optional, a reautorização automática pode estar indisponível por motivos que apenas o navegador conhece. O RP pode verificar se a reautorização automática é realizada analisando a propriedade isAutoSelected.

Isso é útil para avaliar o desempenho da API e melhorar a UX. Além disso, quando ela não está disponível, o usuário pode ser solicitado a fazer login com a mediação explícita do usuário, que é um fluxo com mediation: required.

Um usuário que está se autenticando automaticamente pelo FedCM.

Aplicar a mediação com preventSilentAccess()

A autenticação automática de usuários imediatamente após a saída não seria uma experiência muito boa para o usuário. É por isso que o FedCM tem um período de inatividade de 10 minutos após uma reautorização automática para evitar esse comportamento. Isso significa que a reautenticação automática acontece no máximo uma vez a cada 10 minutos, a menos que o usuário faça login novamente em 10 minutos. A RP precisa chamar navigator.credentials.preventSilentAccess() para solicitar explicitamente que o navegador desative a reautenticação automática quando um usuário sair da RP explicitamente, por exemplo, clicando em um botão de logout.

function signout() {
  navigator.credentials.preventSilentAccess();
  location.href = '/signout';
}

Os usuários podem desativar a reautorização automática nas configurações

Os usuários podem desativar a reautorização automática no menu de configurações:

  • No Chrome para computador, acesse chrome://password-manager/settings > Fazer login automaticamente.
  • No Google Chrome para Android, abra Configurações > Gerenciador de senhas > toque na engrenagem no canto superior direito > Fazer login automaticamente.

Ao desativar o botão, o usuário pode desativar o comportamento de reautorização automática por completo. Essa configuração é armazenada e sincronizada entre dispositivos se o usuário estiver conectado a uma Conta do Google na instância do Chrome e a sincronização estiver ativada.

Desconecte o IdP do RP

Se um usuário já tiver feito login no RP usando o IdP por FedCM, a relação será memorizada pelo navegador localmente como a lista de contas conectadas. O RP pode iniciar uma desconexão invocando a função IdentityCredential.disconnect(). Essa função pode ser chamada em um frame RP de nível superior. O RP precisa transmitir um configURL, o clientId que ele usa no IdP e um accountHint para que o IdP seja desconectado. Uma dica de conta pode ser uma string arbitrária, desde que o endpoint de desconexão possa identificar a conta, por exemplo, um endereço de e-mail ou ID do usuário que não corresponde necessariamente ao ID da conta fornecido pelo endpoint da lista de contas:

// Disconnect an IdP account "account456" from the RP "https://idp.com/". This is invoked on the RP domain.
IdentityCredential.disconnect({
  configURL: "https://idp.com/config.json",
  clientId: "rp123",
  accountHint: "account456"
});

IdentityCredential.disconnect() retorna um Promise. Essa promessa pode gerar uma exceção pelos seguintes motivos:

  • O usuário não fez login no RP usando o IdP por FedCM.
  • A API é invocada de dentro de um iframe sem a política de permissões do FedCM.
  • O configURL é inválido ou o endpoint de desconexão não foi informado.
  • A verificação da Política de Segurança de Conteúdo (CSP) falha.
  • Há uma solicitação de desconexão pendente.
  • O usuário desativou o FedCM nas configurações do navegador.

Quando o endpoint de desconexão do IdP retorna uma resposta, o RP e o IdP são desconectados no navegador, e a promessa é resolvida. O ID das contas desconectadas é especificado na resposta do endpoint de desconexão.

Chamar o FedCM em um iframe entre origens

O FedCM pode ser invocado em um iframe de origem cruzada usando uma política de permissões identity-credentials-get, se o frame pai permitir. Para fazer isso, anexe o atributo allow="identity-credentials-get" à tag iframe da seguinte maneira:

<iframe src="https://fedcm-cross-origin-iframe.glitch.me" allow="identity-credentials-get"></iframe>

Saiba como fazer isso neste exemplo.

Opcionalmente, se o frame pai quiser restringir as origens para chamar o FedCM, envie um cabeçalho Permissions-Policy com uma lista de origens permitidas.

Permissions-Policy: identity-credentials-get=(self "https://fedcm-cross-origin-iframe.glitch.me")

Saiba mais sobre como a Política de permissões funciona em Como controlar recursos do navegador com a Política de permissões.