O UX Collective publicou em 2025 o artigo How authentication friction frustrates users and how to stop it, discutindo por que telas de login continuam sendo um dos maiores pontos de abandono de produto digital. Este artigo explora como a documentação de WebAuthn, relatórios de conversão de login e a experiência em construir gateways de autenticação sustentam as discussões sobre fricção em autenticação.
O ponto que quero puxar não é o de sempre, que autenticação atrapalha. É o mecânico: onde exatamente, dentro do fluxo de login, o sistema decide punir o usuário por uma limitação que é do próprio sistema. E o que mudou nos últimos anos que permite não fazer mais isso.
O que os dados dizem sobre o custo do login
Antes de entrar na mecânica, vale calibrar o tamanho do problema. Pesquisas indicam que 92% dos usuários vão abandonar um site em vez de resetar uma senha esquecida, e 67% dos usuários relatam frustração com processos de login atuais em plataformas digitais. No checkout, o impacto é direto na receita: estima-se que 22% dos compradores abandonaram o carrinho porque o processo de checkout foi longo ou complicado demais.
Esses números às vezes são usados para vender solução mágica. Não é o caso aqui. Eles servem só para justificar por que faz sentido gastar engenharia otimizando algo que muita gente trata como formulário resolvido.
Como a fricção se forma dentro do código
Fricção em autenticação não é uma coisa só. São pelo menos quatro mecanismos distintos que se somam, e cada um tem uma causa técnica diferente.
1. Fricção de digitação
Toda vez que o usuário precisa lembrar e digitar algo, existe uma taxa de erro. Em mobile, essa taxa é maior porque o teclado é menor e o autocorretor atrapalha campos de senha e email. O sistema não controla o dedo do usuário, mas controla o que o campo aceita, o que o teclado sugere e o que acontece quando o usuário erra.
Do lado do HTML, isso vira atributo. Um campo de email sem type="email", sem inputmode="email", sem autocomplete="email" e sem autocapitalize="off" é um campo que está pedindo para o usuário errar em mobile.
<input
type="email"
name="email"
autocomplete="username webauthn"
inputmode="email"
autocapitalize="off"
spellcheck="false"
required
/>
2. Fricção de memória
O usuário precisa lembrar da senha. Se não lembra, entra num fluxo paralelo de recuperação, que geralmente envolve email, código, redefinição, e volta para o login. Cada etapa é um ponto de abandono.
É aqui que o passkey mudou a mecânica. Conditional UI é uma feature do WebAuthn que permite ao usuário fazer login com passkeys diretamente do menu de autofill do browser. Em vez de adicionar um botão separado de sign in with passkey, os passkeys aparecem ao lado das senhas salvas no mesmo dropdown familiar.
O mecanismo por baixo: seu campo de input recebe um atributo autocomplete especial que diz ao browser para incluir passkeys nas sugestões de autofill. Seu JavaScript inicia uma requisição WebAuthn com mediation: conditional, que espera silenciosamente em background até o usuário interagir com o menu de autofill. O browser verifica se o usuário tem passkeys registradas para o site e, se sim, mostra ao lado das senhas salvas. Quando o usuário seleciona uma passkey, o browser dispara o autenticador de plataforma, Face ID, Touch ID, Windows Hello, para verificação.
Uma forma de pensar: no login com senha, o usuário faz o trabalho de lembrar e o servidor faz o trabalho de verificar um segredo compartilhado. Com passkey via conditional UI, o dispositivo do usuário guarda uma chave privada, o servidor guarda a chave pública correspondente, e a autenticação é uma assinatura criptográfica que o servidor consegue verificar sem nunca ver o segredo.
3. Fricção de MFA
MFA existe porque senha não basta. Mas o aumento do uso de autenticação em dois fatores fortaleceu a autenticação baseada em senha fraca e provê mais proteção, mas também criou consideravelmente mais fricção. Códigos de uso único enviados via SMS, apps autenticadores e questões baseadas em conhecimento, todos representam fricção para os usuários.
A pergunta técnica correta não é MFA sim ou não. É: em quais operações o risco justifica o segundo fator, e em quais um sinal passivo já é suficiente? Login de sessão nova em device desconhecido merece MFA. Voltar em device conhecido, com cookie válido, IP compatível e horário coerente, provavelmente não.
4. Fricção de erro
Este é o mecanismo mais evitável e o mais comum. É o formulário que apaga tudo quando o usuário erra um campo. É a mensagem de erro que diz apenas dados inválidos sem dizer qual dado. É o backend que responde 400 sem body útil e o front que renderiza um toast genérico.
Sistema bom declara onde ele para, e não pune a pessoa por aquilo que ele mesmo deixou acontecer. Se o backend aceita senha de 8 a 64 caracteres com símbolo obrigatório, o campo tem que dizer isso antes do submit, não depois. Se o email já está cadastrado, a resposta tem que direcionar para login ou recuperação, não devolver erro de validação.
O que isso significa na prática
Uma implementação mínima de conditional UI, para dar concretude:
// 1. Detecta suporte antes de tentar
if (
window.PublicKeyCredential &&
PublicKeyCredential.isConditionalMediationAvailable
) {
const available =
await PublicKeyCredential.isConditionalMediationAvailable();
if (available) {
// 2. Pede as options ao seu servidor WebAuthn
const options = await fetch('/webauthn/options').then(r => r.json());
// 3. Dispara a requisicao em modo conditional.
// Ela fica pendurada ate o usuario clicar numa sugestao de autofill.
try {
const credential = await navigator.credentials.get({
publicKey: options,
mediation: 'conditional',
});
// 4. Envia a assertion assinada ao servidor para verificacao
await fetch('/webauthn/verify', {
method: 'POST',
body: JSON.stringify(credential),
});
} catch (err) {
// Nao explode a UI. O usuario ainda pode logar por senha.
console.debug('conditional webauthn cancelado', err);
}
}
}
Três detalhes importantes nesse trecho. Primeiro, o isConditionalMediationAvailable é uma checagem prévia obrigatória. Sem ela, você quebra o login em browser antigo. Segundo, o mediation: 'conditional' é o que diferencia do WebAuthn modal, ele não abre popup, ele espera. Terceiro, o catch não deve mostrar erro ao usuário, porque o usuário pode simplesmente ter escolhido logar por senha, e isso é comportamento válido.
Num construtor de landing page que tirou a criação de página da fila da engenharia, tivemos que enfrentar o mesmo tipo de decisão em outro contexto: quando o sistema tem dois caminhos válidos, o desenho da tela precisa deixar ambos vivos e não punir quem escolhe o menos preferido. No caso do login, isso significa que a existência do fluxo passkey não pode degradar o fluxo senha. Se o usuário não tem passkey, ele não pode nem perceber que existe.
Onde essa abordagem quebra
Conditional UI resolve fricção real, mas tem limites concretos que valem a pena conhecer antes de decidir se vai gastar sprint com isso.
Compatibilidade de sistema operacional. Windows 10 não suporta Conditional UI, então foi testada a opção de autocomplete Use a passkey que facilita o fluxo de Cross-Device Authentication. Se sua base tem parcela relevante de Windows 10, você precisa desenhar o fallback, não pode assumir que o autofill vai aparecer.
Interferência de gerenciadores de senha. Se você usa uma extensão de gerenciador de senha, ela pode sequestrar o autofill. Isso pode interferir no fluxo de Conditional UI e prolongar o processo de autenticação. Isso não é bug seu, mas o usuário vai reportar como bug seu.
Ordem do atributo autocomplete importa. O token webauthn no autocomplete habilita Conditional UI e deve aparecer no fim da string autocomplete, porque a gramática do atributo faz parse da direita para a esquerda. Ou seja, é autocomplete="username webauthn" e não autocomplete="webauthn username". É o tipo de detalhe que quebra silencioso.
Passkey sem discoverable credential não aparece. Conditional UI só sugere passkeys que estão como resident key no autenticador. Se seu servidor criou credencial não discoverable, ela não vai aparecer no autofill, mesmo estando registrada.
MFA passivo depende de sinal. Reduzir fricção via risk score, tipo este usuário está no mesmo device e IP de sempre, não pede segundo fator, funciona bem em produto com volume. Em produto novo, você não tem histórico suficiente para o modelo decidir. Nesse caso, cai no default conservador e a fricção volta.
Num dashboard denso em dados de medição de mídia, aprendi que a decisão de onde colocar fricção não é uma escolha binária, é uma calibragem por operação. Login inicial pode ser mais rigoroso, ação destrutiva pode pedir reautenticação, leitura pode ser silenciosa. O mesmo raciocínio se aplica aqui: fricção não é ruim, fricção mal colocada é.
O que não dá para afirmar ainda
Não consegui ler o artigo original do UX Collective, então não sei quais casos específicos ele cita nem qual solução ele prioriza. Se ele defende, por exemplo, magic link como padrão em vez de passkey, essa é uma discussão diferente da que fiz aqui, com trade-offs próprios (magic link tem latência de email e problema de deliverability).
Também não testei o comportamento de conditional UI em todos os browsers combinados com todos os gerenciadores de senha do mercado. As documentações concordam que o suporte cresceu, mas o comportamento fino, quem ganha a briga pelo autofill quando extensão e browser oferecem sugestões concorrentes, varia. Se você vai colocar isso em produção com base grande, teste na sua matriz real de browsers antes.
E não dá para prometer número de conversão. Os 92% de abandono por reset de senha são de pesquisa agregada. Seu produto pode ter usuários muito mais tolerantes ou muito menos, dependendo do valor percebido por trás do login.
Como testar isso você mesmo
Um caminho pequeno para experimentar sem montar servidor WebAuthn do zero:
- Crie uma página HTML com um input de email, com
autocomplete="username webauthn". - Use uma biblioteca WebAuthn pronta no backend (SimpleWebAuthn em Node, py_webauthn em Python) para gerar as options.
- Registre uma passkey de teste no seu próprio device via fluxo modal de registro.
- Recarregue a página de login e clique no input. Você deveria ver a passkey aparecer no autofill do browser.
- Abra o mesmo endereço em browser sem passkey registrada. Você não deve ver nada de diferente do login tradicional. Se ver, seu fallback está errado.
Esse último passo é o mais importante e o mais esquecido. A prova de que a implementação está boa não é o caminho feliz funcionar, é o caminho triste continuar funcionando igual sempre foi.





