Saiba como usar a FedCM para a federação de identidade que preserva a privacidade.
O Gerenciamento de credenciais federadas (FedCM, na sigla em inglês) é uma abordagem que preserva a privacidade para serviços de identidade federados (como "Fazer login com..."). Os usuários podem fazer login em sites sem compartilhar informações pessoais com o serviço de identidade ou o site.
Para saber mais sobre os casos de uso da FedCM, os fluxos de usuários e o roteiro da API, confira a introdução à API da FedCM.
Ambiente de desenvolvimento da FedCM
Você precisa de um contexto seguro (HTTPS ou localhost) no IdP e na RP no Chrome para usar o FedCM.
Depurar código no Chrome no 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 usando um cabo USB com encaminhamento de portas.
Use 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
![Simule a desativação gradual de cookies de terceiros configurando o Chrome para bloqueá-los.](https://developers-dot-devsite-v2-prod.appspot.com/static/privacy-sandbox/assets/images/simulate-third-party-cook-8416bea1ab2b.png?authuser=7&hl=pt-br)
É possível testar como o FedCM funciona sem cookies de terceiros no Chrome antes da aplicação.
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 em um dispositivo móvel acessando Configurações > Configurações do site > Cookies.
Como usar a API FedCM
A integração com o FedCM é feita criando um arquivo conhecido, um arquivo de configuração e endpoints para a lista de contas, emissão de declaração 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
exibido por /.well-known/web-identity
do
eTLD+1 do
IdP.
Por exemplo, se os endpoints do IdP forem exibidos em
https://accounts.idp.example/
, eles precisarão disponibilizar um arquivo conhecido em
https://idp.example/.well-known/web-identity
, bem como 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 do arquivo de configuração do IdP que podem ser especificados como parte do caminho de configURL
em navigator.credentials.get
por RPs. O número de strings de URL na matriz é limitado a um, mas isso pode mudar com seu feedback no futuro.
Criar endpoints e um arquivo de configuração do IdP
O arquivo de configuração do IdP fornece uma lista de endpoints necessários para o navegador. Os IdPs vão hospedar esse arquivo de configuração e os endpoints e URLs necessários. Todas as respostas JSON precisam ser exibidas 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 uma 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 configURL
. Quando
navigator.credentials.get()
é chamado na 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 descubra 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 de contas. |
client_metadata_endpoint (opcional) |
URL do endpoint de metadados do cliente. |
id_assertion_endpoint (obrigatório) |
URL do endpoint de declaração do ID. |
disconnect (opcional) |
URL para o endpoint de desconexão. |
login_url (obrigatório) |
É o URL da página de login em que o usuário pode fazer login no IdP. |
branding (opcional) |
Objeto que contém várias opções de marca. |
branding.background_color (opcional) |
Opção de branding que define a cor 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 branding 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 do ícone é uma matriz com dois parâmetros:
|
O RP pode modificar a string na interface da caixa de diálogo da FedCM usando o valor identity.context
para navigator.credentials.get()
a fim de 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 da FedCM](https://developers-dot-devsite-v2-prod.appspot.com/static/privacy-sandbox/assets/images/RZwmFnyJChjlki8QsnBB.png?authuser=7&hl=pt-br)
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 busca o arquivo de configuração, ele envia solicitações subsequentes para os endpoints do IdP:
![Endpoints do IdP](https://developers-dot-devsite-v2-prod.appspot.com/static/privacy-sandbox/assets/images/idp-endpoints-a67327f46da51.png?authuser=7&hl=pt-br)
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 for compatível com várias contas, esse endpoint retornará todas as contas conectadas.
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
evita que o IdP descubra 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 deve:
- Verifique se a solicitação contém um cabeçalho HTTP
Sec-Fetch-Dest: webidentity
. - Relacione os cookies de sessão com os IDs das contas já conectadas.
- Responda com a lista de contas.
O navegador espera uma resposta JSON que inclua uma propriedade accounts
com uma matriz de informações da conta e 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 de avatar do usuário. |
approved_clients (opcional) |
Uma matriz de IDs de cliente da 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 mostrar seletivamente a conta especificada. |
domain_hints (opcional) |
Uma matriz de todos os domínios aos quais a conta está associada. A parte restrita 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 retornadas é consumida pelo navegador e não ficará disponível para a RP.
Endpoint de metadados do cliente
O endpoint de metadados do cliente do IdP retorna os metadados da parte confiável, como a Política de Privacidade e os Termos de Serviço da parte confiável. A parte restrita precisa 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 tiver se registrado na RP com o IdP.
O navegador envia uma solicitação GET
usando 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:
- Determine a RP para o
client_id
. - Responda com os metadados do cliente.
As propriedades do endpoint de metadados do cliente incluem:
Propriedade | Descrição |
---|---|
privacy_policy_url (opcional) |
RP da Política de Privacidade. |
terms_of_service_url (opcional) |
URL dos Termos de Serviço da parte restrita. |
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 do ID do IdP retorna uma declaração para o usuário conectado.
Quando o usuário faz login em um site da RP usando uma 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 do cliente da parte restrita. |
account_id (obrigatório) |
O ID exclusivo do usuário que está fazendo login. |
nonce (opcional) |
O valor de uso único da solicitação, fornecido pelo RP. |
disclosure_text_shown |
Resulta em uma string "true" ou "false" (em vez de um booleano). O resultado será "false" se o texto de divulgação não for exibido. Isso acontece quando o ID do cliente da parte restrita é incluído na lista de propriedades approved_clients da resposta do endpoint das contas ou quando o navegador tem observado um momento de inscrição no passado na ausência de approved_clients . |
is_auto_selected |
Se for realizada uma reautenticação automática na RP, is_auto_selected indica "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 exija mediação explícita do usuário na autenticação. Se um IdP recebe uma solicitação de token sem essa mediação, ele pode processar a solicitação de maneira diferente. Por exemplo, retorne um código de erro para que a 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:
- Responda à solicitação com o Compartilhamento de recursos entre origens (CORS, na sigla em inglês).
- Verifique se a solicitação contém um cabeçalho HTTP
Sec-Fetch-Dest: webidentity
. - Corresponda o cabeçalho
Origin
com a origem da RP determinada peloclient_id
. Rejeite se não houver correspondência. - Corresponda
account_id
ao ID da conta já conectada. Rejeite se não houver correspondência. - Responda com um token. Se a solicitação for rejeitada, responda com uma resposta de erro.
A forma como o token é emitido depende do IdP, mas, em geral, ele é assinado com informações como ID da conta, ID do cliente, origem do emissor, 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 "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
etemporarily_unavailable
) ou usar qualquer string arbitrária. No segundo caso, o Chrome renderiza a interface de erro com uma mensagem de erro genérica e transmite o código para a RP.url
: identifica uma página da Web legível com informações sobre o erro para fornecer mais detalhes 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 pode acessar a página fornecida na interface do navegador para mais detalhes. O URL precisa estar no mesmo site que o IdPconfigURL
.
// 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
de origem cruzada com cookies com SameSite=None
e um tipo de conteúdo
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 do cliente da parte restrita. |
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 deve:
- Responda à solicitação com o Compartilhamento de recursos entre origens (CORS, na sigla em inglês).
- Verifique se a solicitação contém um cabeçalho HTTP
Sec-Fetch-Dest: webidentity
. - Corresponda o cabeçalho
Origin
com a origem da RP determinada peloclient_id
. Rejeite se não houver correspondência. - Relacione
account_hint
aos IDs das contas que já estão conectadas. - Desconecte a conta de usuário da parte restrita.
- Responda ao navegador com as informações da conta de usuário identificada em um formato JSON.
Um exemplo de payload de resposta JSON é assim:
{
"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 de 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 dessincronizado, por exemplo, quando a sessão expira. Nesse cenário, o
navegador pode permitir dinamicamente que o usuário faça login no IdP por meio do URL da página de login
especificado com o login_url
do arquivo de configuração do IdP.
A caixa de diálogo "FedCM" mostra uma mensagem sugerindo um login, conforme mostrado na imagem a seguir.
![R](https://developers-dot-devsite-v2-prod.appspot.com/static/privacy-sandbox/assets/images/blog/fedcm-120-1.png?authuser=7&hl=pt-br)
Quando o usuário clica no botão Continue, o navegador abre uma janela pop-up para a página de login do IdP.
![Esses](https://developers-dot-devsite-v2-prod.appspot.com/static/privacy-sandbox/assets/images/blog/fedcm-120-2.png?authuser=7&hl=pt-br)
A caixa de diálogo é uma janela normal do navegador que tem cookies primários. O que acontece na caixa de diálogo depende do 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 faz login, o IdP precisa:
- Envie o cabeçalho
Set-Login: logged-in
ou chame a APInavigator.login.setStatus("logged-in")
para informar ao navegador que o usuário fez login. - Chame
IdentityProvider.close()
para fechar a caixa de diálogo.
![R](https://developers-dot-devsite-v2-prod.appspot.com/static/privacy-sandbox/assets/images/blog/fedcm.gif?authuser=7&hl=pt-br)
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 IdP, informa ao navegador o status de login do usuário no IdP. Com essa API, o navegador pode reduzir solicitações desnecessárias ao IdP e minimizar 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 está conectado no IdP ou quando o
usuário está desconectado 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 possíveis valores logged-in
, logged-out
e unknown
. O estado padrão
é unknown
.
Para sinalizar que o usuário está conectado, envie um cabeçalho HTTP Set-Login: logged-in
em uma navegação de nível superior ou uma solicitação de sub-recurso no mesmo site na origem
do IdP:
Set-Login: logged-in
Como alternativa, chame a API JavaScript navigator.login.setStatus("logged-in")
na 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 é definido como logged-in
, a RP que chama FedCM faz solicitações ao endpoint das contas do IdP e exibe as contas disponíveis para o usuário na caixa de diálogo da FedCM.
Para sinalizar que o usuário está desconectado 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 sub-recurso
no mesmo site na origem do IdP:
Set-Login: logged-out
Como alternativa, chame a API JavaScript navigator.login.setStatus("logged-out")
na 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 é logged-out
, a chamada ao FedCM falha silenciosamente, sem fazer uma
solicitação ao endpoint das 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. Talvez o IdP não tenha a chance de sinalizar isso para o navegador no momento em que a FedCM for invocada pela primeira vez. Nesse
caso, o Chrome faz uma solicitação ao endpoint de contas do IdP e atualiza o
status com base na resposta desse endpoint:
- Se o endpoint retornar uma lista de contas ativas, atualize o status para
logged-in
e abra a caixa de diálogo FedCM para mostrar essas contas. - Se o endpoint não retornar contas, atualize o status para
logged-out
e refaça a chamada do FedCM.
Permitir que o usuário faça login com um fluxo de login dinâmico
Mesmo que 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 credenciada para o endpoint das contas quando o status de login é
logged-in
, mas o servidor não retorna contas porque a sessão não está mais
disponível. Nesse cenário, o navegador pode permitir dinamicamente que o usuário faça login
no IdP 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, a parte restrita poderá chamar
navigator.credentials.get()
para solicitar que os usuários façam login na RP
com o IdP.
Antes de chamar a API, confirme se [o FedCM está disponível no navegador do usuário]. Para verificar se a FedCM está disponível, envolva este código em torno da implementação do FedCM:
if ('IdentityCredential' in window) {
// If the feature is available, take action
}
Para solicitar que os usuários façam login no IdP pela RP, faça o seguinte, por exemplo:
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. Impede ataques repetidos. |
loginHint (opcional) |
Ao especificar um dos valores de 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 de domain_hints fornecidos pelos endpoints de contas, a caixa de diálogo FedCM mostra seletivamente a conta especificada. |
O navegador processa 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 exibirá o texto de divulgação "Para continuar com..." se o usuário já tiver se inscrito no RP.
O estado da inscrição é determinado com base no fato de as condições a seguir serem atendidas ou não:
- Se
approved_clients
incluir oclientId
da parte restrita. - Se o navegador lembrar que o usuário já se inscreveu na RP.
Quando a RP chama navigator.credentials.get()
, as seguintes atividades ocorrem:
- O navegador envia solicitações e busca vários documentos:
- O arquivo conhecido e um arquivo de configuração do IdP que declaram os endpoints.
- Uma lista de contas.
- Opcional: URLs da Política de Privacidade e dos Termos de Serviço da RP, recuperados do endpoint de metadados do cliente.
- O navegador exibe a lista de contas que o usuário pode usar para fazer login, além dos Termos de Serviço e da Política de Privacidade, se disponíveis.
- 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.
- A parte restrita pode validar o token para autenticar o usuário.
![chamada de API de login](https://developers-dot-devsite-v2-prod.appspot.com/static/privacy-sandbox/assets/images/login-api-call-a55fdb8f753e8.png?authuser=7&hl=pt-br)
Espera-se que as RPs ofereçam suporte a navegadores que não aceitam FedCM. Portanto, os usuários podem usar um processo de login que não seja do FedCM. Até que os cookies de terceiros sejam eliminados completamente, isso deverá permanecer não problemático.
Depois que o token é validado pelo servidor da RP, a RP pode registrar o usuário ou permitir que ele faça login e inicie uma nova sessão.
API Login Hint
Depois que o usuário faz login, às vezes a parte confiável (RP) pede que ele faça a autenticação 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 de login_hints
buscados no endpoint
da lista de contas, conforme mostrado no exemplo de código a seguir:
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 a loginHint
, a caixa de diálogo "FedCM" mostra uma solicitação de login,
que permite ao usuário fazer login em uma conta do IdP correspondente à dica solicitada pela
RP. Quando o usuário toca na solicitação, 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 dessa 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 é muito comum em cenários corporativos em que o site que está sendo acessado é restrito a um domínio corporativo. Para oferecer uma melhor experiência ao usuário, a API FedCM permite que a parte restrita 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 na RP usando uma conta fora do domínio corporativo, mas só recebe uma mensagem de erro posteriormente (ou silencia quando o login não funcionou), porque o tipo certo de conta não foi usado.
As RPs podem mostrar seletivamente apenas contas correspondentes invocando
navigator.credentials.get()
com a propriedade domainHint
com um dos
valores de domain_hints
buscados no 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 a domainHint
, a caixa de diálogo "FedCM" mostra uma solicitação de login,
que permite ao usuário fazer login em uma conta do IdP correspondente à dica solicitada pela
RP. Quando o usuário toca na solicitação, 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 dessa dica de domínio.
![Exemplo de prompt de login quando nenhuma conta corresponde a "domainHint".](https://developers-dot-devsite-v2-prod.appspot.com/static/privacy-sandbox/assets/images/blog/fedcm-123.jpg?authuser=7&hl=pt-br)
domainHint
.Mostrar uma mensagem de erro
Às vezes, o IdP pode não conseguir emitir um token por motivos legítimos, como quando o cliente não está autorizado, o servidor fica temporariamente indisponível. Se o IdP retornar uma resposta de "erro", a RP poderá capturá-la, e o Chrome notificará o usuário mostrando uma interface do navegador com as informações de erro fornecidas pelo IdP.
![R](https://developers-dot-devsite-v2-prod.appspot.com/static/privacy-sandbox/assets/images/blog/fedcm-120-4.png?authuser=7&hl=pt-br)
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;
}
Autenticar novamente os usuários automaticamente após a autenticação inicial
A reautenticação automática da FedCM ("reautenticação automática") pode permitir que os usuários se autentiquem novamente de maneira automática quando retornarem após a autenticação inicial usando o FedCM. Nesse caso, "a autenticação inicial" significa que o usuário cria uma conta ou faz login no site da parte restrita tocando no botão Continuar como... na caixa de diálogo de login da FedCM pela primeira vez na mesma instância do navegador.
Embora a experiência explícita do usuário faça sentido antes de o usuário criar a conta federada para evitar o rastreamento (que é um dos principais objetivos da FedCM), ela é desnecessariamente complicada depois que o usuário passa por ela uma vez: depois que o usuário concede permissão para permitir a comunicação entre a parte restrita e o IdP, não há um benefício de privacidade ou segurança ao aplicar outra confirmação explícita do usuário para algo que ele já tenha confirmado anteriormente.
Com a reautenticação automática, o navegador muda de 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
que se comporta da mesma
maneira
que faz com
PasswordCredential
e
FederatedCredential
e também é parcialmente compatível com
PublicKeyCredential. A propriedade aceita os quatro valores a seguir:
'optional'
(padrão): reautenticação automática se possível. Caso contrário, exige uma mediação. Recomendamos escolher essa opção na página de login.'required'
: sempre exige uma mediação para prosseguir, por exemplo, clicando no botão "Continuar" na interface. Escolha essa opção se seus usuários precisarem conceder permissão explicitamente sempre que precisarem ser autenticados.'silent'
: reautenticação automática, se possível, e falha silenciosamente, sem precisar de uma mediação. Recomendamos escolher essa opção em outras páginas além da página de login dedicada, mas em que você quer manter os usuários conectados. Por exemplo, uma página de item em um site de frete ou de artigo em um site de notícias.'conditional'
: usado para WebAuthn e não disponível para FedCM no momento.
Com essa chamada, a reautenticação automática acontece 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 utilizou 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.
- A 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 é iniciada assim que o navigator.credentials.get()
do FedCM é invocado.
Quando mediation: optional
, a reautenticação automática pode estar indisponível por motivos que apenas o navegador conhece. O RP pode verificar se a reautenticação automática é realizada examinando a propriedade isAutoSelected
.
Isso é útil para avaliar o desempenho da API e melhorar a UX de acordo.
Além disso, quando não estiver disponível, o usuário poderá ser solicitado a fazer login com a mediação
explícita do usuário, que é um fluxo com mediation: required
.
Aplicar mediação com preventSilentAccess()
A reautenticação automática de usuários imediatamente após o logout não criaria uma
experiência muito boa. É por isso que a FedCM tem um período de silêncio de 10 minutos após uma reautenticaçã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 reautenticação automática nas configurações
Os usuários podem desativar a reautenticação automática no menu de configurações:
- No Chrome para computador, acesse
chrome://password-manager/settings
> Fazer login automaticamente. - No Android Chrome, abra Configurações > Gerenciador de senhas > toque em uma engrenagem no canto superior direito > Login automático.
Ao desativar a opção, o usuário pode desativar o comportamento de reautenticação automática de maneira completa. Essa configuração é armazenada e sincronizada em todos os dispositivos se o usuário tiver feito login em uma Conta do Google na instância do Chrome e a sincronização estiver ativada.
Desconectar o IdP da RP
Se um usuário tiver feito login na RP usando o IdP por FedCM, o
relacionamento será memorizado pelo navegador localmente como a lista de contas
conectadas. A 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. A RP precisa transmitir um configURL
, o clientId
usado
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 que o endpoint da lista de contas forneceu:
// 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 na RP usando o IdP pelo FedCM.
- A API é invocada de dentro de um iframe sem política de permissões do FedCM.
- O configURL é inválido ou não inclui o endpoint de desconexão.
- 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, a 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 a partir de um iframe de origem cruzada
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 de iframe
da seguinte maneira:
<iframe src="https://fedcm-cross-origin-iframe.glitch.me" allow="identity-credentials-get"></iframe>
Confira um exemplo.
Opcionalmente, se o frame pai quiser restringir as origens para chamar a 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.