Saiba como otimizar seu formulário de OTP por SMS e melhorar a experiência do usuário.
Pedir que um usuário forneça a senha única (OTP) enviada por SMS é uma maneira comum de confirmar o número de telefone de um usuário. Há alguns casos de uso para OTP por SMS:
- Autenticação de dois fatores. Além do nome de usuário e da senha, o SMS OTP pode ser usado como um indicador forte de que a conta pertence à pessoa que recebeu o SMS OTP.
- Verificação do número de telefone. Alguns serviços usam um número de telefone como o identificador principal do usuário. Nesses serviços, os usuários podem inserir o número de telefone e o OTP recebido por SMS para provar a identidade. Às vezes, ela é combinada com um PIN para constituir uma autenticação de dois fatores.
- Recuperação de conta. Quando um usuário perde o acesso à conta, é necessário haver uma maneira de recuperá-la. Enviar um e-mail para o endereço de e-mail registrado ou um SMS OTP para o número de telefone são métodos comuns de recuperação de conta.
- Confirmação de pagamento: em sistemas de pagamento, alguns bancos ou emissores de cartão de crédito solicitam uma autenticação adicional do pagador por motivos de segurança. O SMS OTP é comumente usado para esse fim.
Esta postagem explica as práticas recomendadas para criar um formulário de OTP por SMS para os casos de uso acima.
Lista de verificação
Para oferecer a melhor experiência do usuário com o OTP por SMS, siga estas etapas:
- Use o elemento
<input>
com:type="text"
inputmode="numeric"
autocomplete="one-time-code"
- Use
@BOUND_DOMAIN #OTP_CODE
como a última linha da mensagem SMS de OTP. - Use a API WebOTP.
Use o elemento <input>
Usar um formulário com um elemento <input>
é a prática recomendada mais importante que você
pode seguir, porque funciona em todos os navegadores. Mesmo que outras sugestões desta
postagem não funcionem em alguns navegadores, o usuário ainda poderá inserir e enviar o OTP
manualmente.
<form action="/verify-otp" method="POST">
<input type="text"
inputmode="numeric"
autocomplete="one-time-code"
pattern="\d{6}"
required>
</form>
Confira a seguir algumas ideias para garantir que um campo de entrada aproveite ao máximo a funcionalidade do navegador.
type="text"
Como os OTPs geralmente são números de cinco ou seis dígitos, o uso de
type="number"
em um campo de entrada pode parecer intuitivo, porque muda o teclado
do dispositivo móvel para números apenas. Isso não é recomendado porque o navegador espera que um
campo de entrada seja um número contável, e não uma sequência de vários números,
o que pode causar um comportamento inesperado. O uso de type="number"
faz com que os botões para cima e para baixo
sejam exibidos ao lado do campo de entrada. Ao pressionar esses botões,
o número é aumentado ou diminuído e os zeros anteriores podem ser removidos.
Use type="text"
. Isso não vai transformar o teclado do dispositivo móvel em números
somente, mas tudo bem, porque a próxima dica para usar inputmode="numeric"
faz
isso.
inputmode="numeric"
Use inputmode="numeric"
para mudar o teclado do dispositivo móvel para números apenas.
Alguns sites usam type="tel"
para campos de entrada de OTP, porque ele também
transforma o teclado do dispositivo móvel em números apenas (incluindo *
e #
) quando
em foco. Esse hack foi usado no passado quando o inputmode="numeric"
não tinha suporte amplo. Como o Firefox começou a oferecer suporte a
inputmode="numeric"
,
não é necessário usar o hack type="tel"
semanticamente incorreto.
autocomplete="one-time-code"
O atributo autocomplete
permite que os desenvolvedores especifiquem qual permissão o navegador
tem para fornecer assistência de preenchimento automático e informa o navegador sobre o
tipo de informação esperado no campo.
Com autocomplete="one-time-code"
, sempre que um usuário receber uma mensagem SMS enquanto um
formulário estiver aberto, o sistema operacional vai analisar o OTP no SMS de forma heurística e
o teclado vai sugerir que o usuário insira o OTP. Ele funciona apenas no Safari 12 e
versões mais recentes no iOS, iPadOS e macOS, mas recomendamos que você o use, porque é uma
maneira fácil de melhorar a experiência de OTP por SMS nessas plataformas.
O autocomplete="one-time-code"
melhora a experiência do usuário, mas você pode fazer mais
garantindo que a mensagem SMS esteja em conformidade com o formato de mensagem
de origem.
Formatar o texto do SMS
Melhore a experiência do usuário ao inserir um OTP alinhando-se à especificação de códigos de uso único vinculados à origem enviados por SMS.
A regra de formato é simples: termine a mensagem SMS com o domínio do destinatário
precedido por @
e o OTP precedido por #
.
Exemplo:
Your OTP is 123456
@web-otp.glitch.me #123456
Usar um formato padrão para mensagens de OTP facilita a extração de códigos delas e torna o processo mais confiável. A associação de códigos OTP a sites dificulta que os usuários sejam enganados para fornecer um código a sites maliciosos.
O uso desse formato oferece alguns benefícios:
- O OTP será vinculado ao domínio. Se o usuário estiver em domínios diferentes do especificado na mensagem SMS, a sugestão de OTP não vai aparecer. Isso também reduz o risco de ataques de phishing e possíveis invasões de contas.
- O navegador agora poderá extrair o OTP de forma confiável sem depender de heurísticas misteriosas e instáveis.
Quando um site usa autocomplete="one-time-code"
, o Safari com iOS 14 ou mais recente
sugere o OTP seguindo as regras acima.
Esse formato de mensagem de SMS também beneficia outros navegadores além do Safari. O Chrome, o Opera
e o Vivaldi no Android também oferecem suporte à regra de códigos de uso único com limite de origem com
a API WebOTP, mas não por meio de autocomplete="one-time-code"
.
Usar a API WebOTP
A API WebOTP (link em inglês) dá acesso ao OTP
recebido em uma mensagem SMS. Ao chamar
navigator.credentials.get()
com o tipo otp
(OTPCredential
), em que transport
inclui sms
, o site
vai aguardar que um SMS que obedece aos códigos de uso único vinculados à origem seja
enviado e que o acesso seja concedido pelo usuário. Depois que o OTP é transmitido para o JavaScript,
o site pode usá-lo em um formulário ou fazer POST diretamente para o servidor.
navigator.credentials.get({
otp: {transport:['sms']}
})
.then(otp => input.value = otp.code);
Saiba como usar a API WebOTP em detalhes em Verificar números de telefone na Web
com a API WebOTP ou copie e cole o snippet abaixo. Verifique
se o elemento <form>
tem um atributo action
e method
definido corretamente.
// Feature detection
if ('OTPCredential' in window) {
window.addEventListener('DOMContentLoaded', e => {
const input = document.querySelector('input[autocomplete="one-time-code"]');
if (!input) return;
// Cancel the WebOTP API if the form is submitted manually.
const ac = new AbortController();
const form = input.closest('form');
if (form) {
form.addEventListener('submit', e => {
// Cancel the WebOTP API.
ac.abort();
});
}
// Invoke the WebOTP API
navigator.credentials.get({
otp: { transport:['sms'] },
signal: ac.signal
}).then(otp => {
input.value = otp.code;
// Automatically submit the form when an OTP is obtained.
if (form) form.submit();
}).catch(err => {
console.log(err);
});
});
}
Foto de Jason Leung no Unsplash.