Práticas recomendadas para formulários de OTP por SMS

Saiba como otimizar seu formulário de OTP por SMS e melhorar a experiência do usuário.

Pedir para um usuário fornecer a OTP (senha única) 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, a OTP por SMS pode ser usada como um forte sinal de que a conta é de propriedade da pessoa que recebeu a OTP por SMS.
  • 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 a OTP recebida por SMS para comprovar a identidade. Às vezes, ele é combinado 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 forma de recuperá-la. Enviar um e-mail para o endereço de e-mail registrado ou uma OTP por SMS para o número de telefone são métodos comuns de recuperação de conta.
  • Confirmação de pagamento nos sistemas de pagamento, alguns bancos ou emissores de cartões de crédito solicitam autenticação adicional do pagador por motivos de segurança. O OTP por SMS é comumente usado para essa finalidade.

Nesta postagem, explicamos 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 ao usuário com 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.

Usar o elemento <input>

Usar um formulário com um elemento <input> é a prática recomendada mais importante, porque funciona em todos os navegadores. Mesmo que outras sugestões desta postagem não funcionem em algum navegador, o usuário ainda poderá inserir e enviar a 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 as OTPs geralmente são números de cinco ou seis dígitos, o uso de type="number" para um campo de entrada pode parecer intuitivo porque muda o teclado do dispositivo móvel para apenas números. Isso não é recomendado porque o navegador espera que um campo de entrada seja um número contável em vez de 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 mostrados ao lado do campo de entrada. Pressione esses botões aumenta ou diminui o número e pode remover os zeros anteriores.

Use type="text" Isso não transforma o teclado móvel em apenas números, mas tudo bem, porque a próxima dica para usar inputmode="numeric" faz esse trabalho.

inputmode="numeric"

Use inputmode="numeric" para mudar o teclado móvel para apenas números.

Alguns sites usam type="tel" para campos de entrada de OTP, já que ele também transforma o teclado do dispositivo móvel em números (incluindo * e #) quando em foco. Essa invasão foi usada no passado quando o inputmode="numeric" não tinha suporte amplo. Desde que o Firefox passou a oferecer suporte a inputmode="numeric", não é necessário usar a invasão type="tel" semanticamente incorreta.

autocomplete="one-time-code"

O atributo autocomplete permite que os desenvolvedores especifiquem qual permissão o navegador tem para oferecer assistência de preenchimento automático e informa ao navegador sobre o tipo de informação esperada no campo.

Com autocomplete="one-time-code" sempre que um usuário recebe uma mensagem SMS enquanto um formulário está aberto, o sistema operacional analisa a OTP no SMS de forma heurística, e o teclado sugere a OTP para o usuário inserir. Ela funciona apenas no Safari 12 e mais recentes no iOS, iPadOS e macOS, mas recomendamos o uso, porque é uma maneira fácil de melhorar a experiência de OTP por SMS nessas plataformas.

`Autocomplete="one-time-code"` em ação.

autocomplete="one-time-code" melhora a experiência do usuário, mas você pode fazer mais o que é possível garantir que a mensagem SMS esteja em conformidade com o formato de mensagem vinculada à origem.

Formatar o texto SMS

Melhore a experiência do usuário ao inserir uma OTP alinhando-se à especificação de códigos únicos vinculados à origem entregues por SMS.

A regra de formatação é simples: termine a mensagem SMS com o domínio do destinatário precedido por @ e a OTP precedida por #.

Exemplo:

Your OTP is 123456

@web-otp.glitch.me #123456

O uso de um formato padrão para mensagens OTP torna a extração de códigos deles mais fácil e confiável. A associação de códigos OTP a sites torna mais difícil induzir os usuários a fornecer um código a sites maliciosos.

O uso desse formato oferece alguns benefícios:

  • A OTP vai estar vinculada ao domínio. Se o usuário estiver em um domínio diferente do especificado na mensagem SMS, a sugestão de OTP não aparecerá. Isso também reduz o risco de ataques de phishing e possíveis invasões de conta.
  • Agora, o navegador poderá extrair a OTP de maneira confiável, sem depender de uma heurística misteriosa e fragmentada.

Quando um site usa o autocomplete="one-time-code", o Safari com iOS 14 ou mais recente sugere a OTP seguindo as regras acima.

Esse formato de mensagem SMS também beneficia outros navegadores além do Safari. O Chrome, o Opera e o Vivaldi no Android também são compatíveis com a regra de códigos únicos vinculados à origem com a API WebOTP, mas não pelo autocomplete="one-time-code".

Usar a API WebOTP

A API WebOTP fornece acesso à OTP recebida em uma mensagem SMS. Ao chamar navigator.credentials.get() com o tipo otp (OTPCredential), em que transport inclui sms, o site esperará que um SMS compatível com os códigos únicos vinculados à origem seja entregue e tenha acesso ao usuário. Depois que a OTP é transmitida para o JavaScript, o site pode usá-la em um formulário ou fazer o POST dela diretamente para o servidor.

navigator.credentials.get({
  otp: {transport:['sms']}
})
.then(otp => input.value = otp.code);
API WebOTP em ação.

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 a seguir. Verifique se o elemento <form> tem um atributo action e method definidos 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 (links em inglês).