Verifique números de telefone na web com a API WebOTP
Ajude os usuários com OTPs (senhas de uso único) recebidos por SMS
O que é a API WebOTP? #
Hoje em dia, a maioria das pessoas no mundo possui um dispositivo móvel e os desenvolvedores geralmente usam números de telefone como um identificador de usuários de seus serviços.
Existem diversas maneiras de verificar números de telefone, mas uma senha de uso único (OTP - "One-Time Password") gerada aleatoriamente e enviada por SMS é uma das mais comuns. O envio desse código de volta ao servidor do desenvolvedor demonstra o controle do número de telefone.
Esta ideia já foi implantada em diversos cenários para obter:
- Número de telefone como identificador para o usuário. Ao se inscrever em um novo serviço, alguns sites pedem um número de telefone em vez de um endereço de e-mail e o usam como um identificador de conta.
- Verificação em duas etapas. Ao fazer login, um site pede um código de uso único enviado via SMS além de uma senha ou outro fator de conhecimento para segurança adicional.
- Confirmação de pagamento. Quando um usuário está fazendo um pagamento, solicitar um código de uso único enviado por SMS pode ajudar a verificar a intenção da pessoa.
O processo atual cria atrito para os usuários. Encontrar uma OTP numa mensagem SMS e, em seguida, ter que copiá-la e colá-la no formulário é complicado, reduzindo as taxas de conversão em jornadas críticas do usuário. Facilitar esse processo tem sido um pedido de longa data para a web de muitos dos maiores desenvolvedores globais. O Android tem uma API que faz exatamente isso. O mesmo acontece com o iOS e o Safari.
A API WebOTP permite que seu aplicativo receba mensagens especialmente formatadas vinculadas ao domínio de seu aplicativo. A partir daí, você pode extrair programaticamente uma OTP a partir de uma mensagem SMS e verificar um número de telefone para o usuário com mais facilidade.
Veja em ação #
Vamos supor que um usuário queira verificar seu número de telefone com um site. O site envia uma mensagem de texto ao usuário por SMS e o usuário insere a OTP da mensagem para verificar a propriedade do número de telefone.
Para o usuário, com a API WebOTP, essas etapas são tão fáceis quanto um toque, conforme mostrado no vídeo. Quando a mensagem de texto chega, uma folha inferior aparece e solicita que o usuário verifique seu número de telefone. Depois de clicar no botão Verificar da folha inferior, o navegador cola a OTP no formulário e ela é enviada sem que o usuário precise clicar em Continuar.
Todo o processo está diagramado na imagem abaixo.
Experimente a demonstração você mesmo. Ela não pede seu número de telefone ou envia um SMS para o seu dispositivo, mas você pode enviar um de outro dispositivo copiando o texto exibido na demonstração. Isto funciona porque, ao usar a API WebOTP, não importa quem é o remetente .
- Acesse https://web-otp.glitch.me no Chrome 84 ou posterior em um dispositivo Android.
- Envie para o seu telefone a seguinte mensagem de texto SMS a partir de outro telefone.
Your OTP is: 123456.
@web-otp.glitch.me #12345
Você recebeu o SMS e viu o prompt para inserir o código na área de entrada? É assim que a API WebOTP funciona para os usuários.
O uso da API WebOTP consiste em três partes:
- Uma tag
<input>
devidamente anotada - JavaScript em sua aplicação web
- Mensagem de texto formatada enviada por SMS.
Primeiro vou falar da tag <input>
.
Anote uma tag <input>
#
A WebOTP funciona sozinha sem qualquer anotação HTML, mas para compatibilidade entre navegadores, eu recomendo fortemente que você adicione autocomplete="one-time-code"
à tag <input>
onde você espera que o usuário insira uma OTP.
Isto permite que o Safari 14 ou posterior sugira que o usuário preencha automaticamente o <input>
com uma OTP ao receber um SMS no formato descrito em Formate a mensagem SMS, embora ele não suporte WebOTP.
HTML
<form>
<input autocomplete="one-time-code" required/>
<input type="submit">
</form>
Use a API WebOTP #
Como a WebOTP é simples, basta copiar e colar o código a seguir. Seja como for, eu explicarei o que está acontecendo.
JavaScript
if ('OTPCredential' in window) {
window.addEventListener('DOMContentLoaded', e => {
const input = document.querySelector('input[autocomplete="one-time-code"]');
if (!input) return;
const ac = new AbortController();
const form = input.closest('form');
if (form) {
form.addEventListener('submit', e => {
ac.abort();
});
}
navigator.credentials.get({
otp: { transport:['sms'] },
signal: ac.signal
}).then(otp => {
input.value = otp.code;
if (form) form.submit();
}).catch(err => {
console.log(err);
});
});
}
Detecção de recursos #
A detecção de recursos é a mesma que para muitas outras APIs. Escutar o evento DOMContentLoaded
vai esperar que a árvore DOM esteja pronta para a consulta.
JavaScript
if ('OTPCredential' in window) {
window.addEventListener('DOMContentLoaded', e => {
const input = document.querySelector('input[autocomplete="one-time-code"]');
if (!input) return;
…
const form = input.closest('form');
…
});
}
Processe a OTP #
A própria API WebOTP é bastante simples. Use navigator.credentials.get()
para obter a OTP. A WebOTP adiciona uma nova opção otp
a esse método. Ela possui apenas uma propriedade: transport
, cujo valor deve ser um array com a string 'sms'
.
JavaScript
…
navigator.credentials.get({
otp: { transport:['sms'] }
…
}).then(otp => {
…
Isto dispara o fluxo de permissão do navegador quando uma mensagem SMS chegar. Se a permissão for concedida, a promessa retornada será resolvida com um objeto OTPCredential
.
Conteúdo do objeto OTPCredential
obtido
{
code: "123456" // Obtained OTP
type: "otp" // `type` is always "otp"
}
Em seguida, passe o valor da OTP para o campo <input>
. O envio direto do formulário eliminará a etapa que exige que o usuário toque num botão.
JavaScript
…
navigator.credentials.get({
otp: { transport:['sms'] }
…
}).then(otp => {
input.value = otp.code;
if (form) form.submit();
}).catch(err => {
console.error(err);
});
…
Abortando a mensagem #
Caso o usuário insira manualmente uma OTP e envie o formulário, você pode cancelar a chamada get()
usando uma instância AbortController
no objeto options
.
JavaScript
…
const ac = new AbortController();
…
if (form) {
form.addEventListener('submit', e => {
ac.abort();
});
}
…
navigator.credentials.get({
otp: { transport:['sms'] },
signal: ac.signal
}).then(otp => {
…
Formate a mensagem SMS #
A API em si deve parecer bastante simples, mas há algumas coisas que você deve saber antes de usá-la. A mensagem deve ser enviada depois que navigator.credentials.get()
for chamado e deve ser recebida no dispositivo onde get()
foi chamado. Por fim, a mensagem deve respeitar a seguinte formatação:
- A mensagem começa com um texto legível (opcional) que contém uma sequência alfanumérica de quatro a dez caracteres com pelo menos um número deixando a última linha para a URL e a OTP.
- A parte do domínio da URL do site que chamou a API deve ser precedida por
@
. - A URL deve conter um sinal de hash ('
#
') seguido pela OTP.
Por exemplo:
Your OTP is: 123456.
@www.example.com #123456
Eis alguns exemplos ruins:
Demos #
Experimente várias mensagens com a demonstração: https://web-otp.glitch.me
Você também pode fazer um fork e criar sua própria versão: https://glitch.com/edit/#!/web-otp.
Use WebOTP de um iframe de origem cruzada #
A inserção de uma SMS OTP para um iframe de origem cruzada é tipicamente usada para confirmação de pagamento, principalmente com 3D Secure. Tendo o formato comum para suportar iframes de origem cruzada, a API WebOTP entrega OTPs vinculados a origens aninhadas. Por exemplo:
- Um usuário visita
shop.example
para comprar um par de sapatos com cartão de crédito. - Depois de inserir o número do cartão de crédito, o provedor de pagamento integrado mostra um formulário do site
bank.example
num iframe solicitando que o usuário verifique seu número de telefone para um checkout rápido. - O site
bank.example
envia um SMS que contém uma OTP ao usuário para que ele possa inseri-la e verificar sua identidade.
Para usar a API WebOTP de um iframe de origem cruzada, você precisa fazer duas coisas:
- Anotar tanto a origem do frame superior como a origem do iframe na mensagem de texto SMS.
- Configure a política de permissões para permitir que o iframe de origem cruzada receba a OTP diretamente do usuário.
Você pode experimentar a demonstração em https://web-otp-iframe-demo.stackblitz.io .
Anote origens vinculadas à mensagem de texto SMS #
Quando a API WebOTP é chamada de dentro de um iframe, a mensagem de texto SMS deve incluir a origem do frame de nível superior precedida por @
seguida pela OTP precedida por #
e a origem do iframe precedida por @
na última linha.
Your verification code is 123456
@shop.example #123456 @bank.exmple
Configure a política de permissões #
Para usar a WebOTP num iframe de origem cruzada, o incorporador deve conceder acesso a essa API por meio da política de permissões otp-credentials para evitar comportamento indesejado. Em geral, existem duas maneiras de atingir esse objetivo:
via cabeçalho HTTP:
Permissions-Policy: otp-credentials=(self "https://bank.example")
via atributo iframe allow
:
<iframe src="https://bank.example/…" allow="otp-credentials"></iframe>
Veja mais exemplos de como especificar uma política de permissões.
Perguntas frequentes #
A caixa de diálogo não aparece, embora eu esteja enviando uma mensagem formatada corretamente. O que há de errado? #
Existem algumas questões que devem ser observadas ao testar a API:
- Se o número de telefone do remetente estiver incluído na lista de contatos do destinatário, esta API não será acionada devido ao design da SMS User Consent API subjacente.
- Se você estiver usando um perfil de trabalho em seu dispositivo Android e a WebOTP não funcionar, tente instalá-la e usar o Chrome no seu perfil pessoal (ou seja, o mesmo perfil que você recebe mensagens SMS).
Verifique novamente o formato para ver se seu SMS está formatado corretamente.
Esta API é compatível entre navegadores diferentes? #
O Chromium e o WebKit concordaram com o formato de mensagem de texto SMS e a Apple anunciou o suporte do Safari para ele a partir do iOS 14 e macOS Big Sur. Embora o Safari não suporte a API JavaScript do WebOTP, ao anotar o elemento input
com autocomplete=["one-time-code"]
, o teclado padrão sugere automaticamente que você insira o OTP se a mensagem SMS estiver em conformidade com o formato.
É seguro usar SMS como forma de autenticação? #
Embora a SMS OTP seja útil para verificar um número de telefone quando o número é fornecido pela primeira vez, a verificação do número de telefone via SMS deve ser usada com cuidado na reautenticação, pois os números de telefone podem ser sequestrados e reciclados pelas operadoras. A WebOTP é um mecanismo de reautenticação e recuperação conveniente, mas os serviços devem combiná-lo com fatores adicionais, como um desafio de conhecimento ou usar a Web Authentication API para autenticação forte.
Onde posso relatar bugs na implementação do Chrome? #
Você encontrou um bug na implementação do Chrome?
- Registre um bug em https://new.crbug.com. Inclua o máximo de detalhes que puder, instruções simples para reproduzi-lo e defina Componentes para
Blink>WebOTP
.
Como posso ajudar neste recurso? #
Você planeja usar a API WebOTP? Seu apoio público nos ajuda a priorizar os recursos e mostra a outros fornecedores de navegadores como é importante apoiá-los. Envie um tweet para @ChromiumDev usando a hashtag #WebOTP
e diga-nos onde e como você está usando.