Atualizações do FedCM: API Login Status, API Error e API Flag selecionada automaticamente

O Chrome 120 está enviando a API Login Status para a FedCM. A API Login Status (anteriormente conhecida como API IdP Sign-in Status) permite que sites, especialmente provedores de identidade, sinalizem para o navegador quando os usuários estão fazendo login e logout. Esse sinal é usado pela FedCM para resolver um problema de ataque de tempo silencioso e, ao fazer isso, permite que a FedCM opere sem cookies de terceiros. Essa atualização aborda as últimas mudanças incompatíveis com versões anteriores que identificamos anteriormente na intent original de envio do FedCM como parte do nosso escopo de trabalho.

Embora a API Login Status melhore a propriedade de privacidade e a usabilidade, ela é uma alteração incompatível com versões anteriores depois do envio. Se você tiver uma implementação atual do FedCM, atualize-a seguindo as instruções a seguir.

Além disso, o Chrome está lançando dois novos recursos de gerenciamento de credenciais federadas (FedCM, na sigla em inglês):

  • API Error: notifique os usuários quando a tentativa de login falhar com uma interface nativa com base na resposta do servidor do endpoint de declaração de ID, se houver.
  • API Auto-Selected Flag: notifique o provedor de identidade (IdP) e a parte confiável (RP) se uma credencial for selecionada automaticamente no fluxo.

API Login Status

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 para o IdP e minimizar possíveis ataques de tempo.

Informar o navegador sobre o status de login do usuário

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 os possíveis valores logged-in, logged-out e unknown. O estado padrão é unknown.

Para indicar 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-recursos de mesma origem:

Set-Login: logged-in

Como alternativa, chame a API JavaScript navigator.login.setStatus('logged-in') da origem do IdP:

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 o FedCM faz solicitações para o endpoint da lista de contas do IdP e exibe as contas disponíveis para o usuário na caixa de diálogo do FedCM.

Para indicar 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 em uma solicitação de sub-recursos de mesma origem:

Set-Login: logged-out

Como alternativa, chame a API JavaScript navigator.login.setStatus('logged-out') da origem do IdP:

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 do FedCM falha silenciosamente, sem fazer uma solicitação ao endpoint da lista de contas do IdP.

O status unknown é definido antes que o IdP envie um indicador usando a API Login Status. Apresentamos esse status para uma transição melhor, porque um usuário pode já ter feito login no IdP quando enviamos essa API. O IdP pode não ter a chance de sinalizar isso ao navegador no momento em que o FedCM é invocado pela primeira vez. Nesse caso, fazemos uma solicitação para o endpoint da lista de contas do IdP e atualizamos 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 do 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.

E se a sessão do usuário expirar? Permita que o usuário faça login por meio de um fluxo de login dinâmico.

Embora o IdP continue informando o status de login do usuário ao navegador, o status pode estar fora de sincronia, como quando a sessão expira. O navegador tenta enviar uma solicitação credenciada para o endpoint da lista 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 dinamicamente que o usuário faça login no IdP por uma janela de diálogo.

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

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

Quando o usuário clica no botão Continuar, o navegador abre uma caixa de diálogo na página de login do IdP.

Um exemplo de caixa de diálogo.
Uma caixa de diálogo de exemplo mostrada após o clique no botão de login no IdP.

O URL da página de login é especificado com login_url como parte do arquivo de configuração do IdP.

{
  "accounts_endpoint": "/auth/accounts",
  "client_metadata_endpoint": "/auth/metadata",
  "id_assertion_endpoint": "/auth/idtokens",
  "login_url": "/login"
  }
}

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 fizer login, o IdP precisa:

  • 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 uma RP depois de fazer login no IdP usando o FedCM.
Um usuário faz login em um RP depois de fazer login no IdP usando o FedCM.

Teste o comportamento da API Login Status em nossa demonstração.

  1. Toque no botão Go to the IdP and sign in.
  2. Faça login com uma conta arbitrária.
  3. Selecione Sessão expirada no menu suspenso Status da conta.
  4. Pressione o botão Atualizar informações pessoais.
  5. Toque no botão Visit the RP to experiment FedCM.

É possível acompanhar o login do IdP no comportamento do módulo.

API Error

Quando o Chrome envia uma solicitação para o endpoint de declaração de ID (por exemplo, quando um usuário clica no botão Continuar como na IU do FedCM ou a reautenticação automática é acionada), o IdP pode não conseguir emitir um token por motivos legítimos. Por exemplo, se o cliente não for autorizado, o servidor ficará temporariamente indisponível e assim por diante. Atualmente, o Chrome falha a solicitação silenciosamente em caso de esses erros e só notifica a RP rejeitando a promessa.

Com a API Error, o Chrome notifica o usuário mostrando uma interface nativa com as informações de erro fornecidas pelo IdP.

Uma caixa de diálogo do FedCM mostrando a mensagem de erro após a tentativa de login do usuário falhar. A string está associada ao tipo de erro.
Uma caixa de diálogo do FedCM mostrando a mensagem de erro após a tentativa de login do usuário falhar. A string está associada ao tipo de erro.

API IdP HTTP

Na resposta id_assertion_endpoint, o IdP pode retornar um token ao navegador se ele puder ser emitido mediante solicitação. Nesta proposta, caso um token não possa ser emitido, o IdP pode retornar uma resposta de "erro", que tem dois novos campos opcionais:

  1. code
  2. url
// id_assertion_endpoint response
{
  "error": {
     "code": "access_denied",
     "url": "https://idp.example/error?type=access_denied"
  }
}

Para o código, 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 o último tipo, o Chrome renderiza a interface de erro com uma mensagem de erro genérica e transmite o código para a RP.

Para url, ele identifica uma página da Web legível com informações sobre o erro para fornecer mais informações sobre ele 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 configURL do IdP.

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;
}

API Auto-Selected Flag

mediation: optional é o comportamento padrão de mediação do usuário na API Credential Management e aciona uma nova autenticação automática quando possível. No entanto, a reautenticação automática pode não estar disponível por motivos que apenas o navegador sabe. Quando ela não está disponível, o usuário pode ser solicitado a fazer login com mediação explícita do usuário, que é um fluxo com propriedades diferentes.

  • Do ponto de vista de um autor de chamada da API, quando ele recebe um token de ID, não tem visibilidade se foi resultado de um fluxo de reautenticação automática. Isso dificulta a avaliação do desempenho da API e a melhoria da UX.
  • Do ponto de vista do IdP, eles também não conseguem dizer se uma reautenticação automática ocorreu ou não para a avaliação de desempenho. Além disso, o envolvimento de uma mediação explícita do usuário pode ajudar a 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 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 a RP possa chamar a API FedCM novamente com mediation: required.

Portanto, fornecer visibilidade do fluxo de reautenticação automática seria benéfico para os desenvolvedores.

Com a API Flag selecionada automaticamente, o Chrome compartilha se uma permissão explícita do usuário foi adquirida ao tocar no botão Continuar como com o IdP e o RP sempre que ocorre uma reautenticação automática ou uma mediação explícita. O compartilhamento só acontece depois que a permissão do usuário é concedida para a comunicação do IdP/RP.

Compartilhamento de IdP

Para compartilhar as informações com a permissão de usuário do IdP, o Chrome inclui is_auto_selected=true na solicitação POST enviada ao id_assertion_endpoint:

POST /fedcm_assertion_endpoint HTTP/1.1
Host: 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=Ct0D&disclosure_text_shown=true&is_auto_selected=true

Compartilhamento com a parte restrita

O navegador pode compartilhar as informações com a RP em isAutoSelected via IdentityCredential:

const cred = await navigator.credentials.get({
  identity: {
    providers: [{
      configURL: 'https://idp.example/manifest.json',
      clientId: '1234'
    }]
  }
});

if (cred.isAutoSelected !== undefined) {
  const isAutoSelected = cred.isAutoSelected;
}

Interaja e compartilhe feedback

Se você tiver feedback ou encontrar algum problema durante o teste, compartilhe-o em crbug.com (link em inglês).

Foto de Girl com chapéu vermelho no Unsplash (links em inglês)