Desenho de uma mulher usando OTP para fazer login num aplicativo web.

Verifique números de telefone na web com a API WebOTP

Ajude os usuários com OTPs (senhas de uso único) recebidos por SMS

Published on Updated on

Translated to: English, Español, 한국어, 中文, Pусский

Importante

Se você quiser conhecer mais práticas recomendadas gerais relacionadas a SMS OTP, incluindo a API WebOTP, veja as Práticas recomendadas para SMS OTP.

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.

Warning

Invasores podem falsificar um SMS e sequestrar o número de telefone de uma pessoa. As operadoras também podem reciclar números de telefone para novos usuários depois do encerramento de uma conta. Embora a técnica SMS OTP seja útil para verificar um número de telefone para os casos de uso acima, recomendamos a utilização de formas adicionais e mais fortes de autenticação (como múltiplos fatores e a Web Authentication API para estabelecer novas sessões para esses usuários.

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.

Diagrama da WebOTP API

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 .

  1. Acesse https://web-otp.glitch.me no Chrome 84 ou posterior em um dispositivo Android.
  2. 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.

Importante

Se a caixa de diálogo não aparecer para você, dê uma olhada nas Perguntas Frequentes.

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');

});
}
Caution

A API WebOTP requer uma origem segura (HTTPS). A detecção de recurso num site usando HTTP irá falhar.

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:

Exemplo de texto SMS malformadoPor que não funciona
Here is your code for @example.com #123456@ deve ser o primeiro caractere da última linha.
Your code for @example.com is #123456@ deve ser o primeiro caractere da última linha.
Your verification code is 123456

@example.com\t#123456
Espera-se um único espaço entre @host e #code.
Your verification code is 123456

@example.com #123456
Espera-se um único espaço entre @host e #code.
Your verification code is 123456

@ftp://example.com #123456
O esquema de URL não pode ser incluído.
Your verification code is 123456

@https://example.com #123456
O esquema de URL não pode ser incluído.
Your verification code is 123456

@example.com:8080 #123456
A porta não pode ser incluída.
Your verification code is 123456

@example.com/foobar #123456
O caminho não pode ser incluído.
Your verification code is 123456

@example .com #123456
Não pode haver espaços em branco no domínio.
Your verification code is 123456

@domain-forbiden-chars-#%/:<>?@[] #123456
Não pode haver caracteres proibidos no domínio.
@example.com #123456

Mambo Jumbo
@host e #code devem ser a última linha.
@example.com #123456

App hash #oudf08lkjsdf834
@host e #code devem ser a última linha.
Your verification code is 123456

@example.com 123456
Falta #.
Your verification code is 123456

example.com #123456
Falta #.
Hi mom, did you receive my last textFalta @ e #.

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.
WebOTP API num iframe em ação.

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.

Atualmente o Chrome só suporta chamadas da API WebOTP a partir de iframes de origem cruzada que não têm mais do que uma origem única em sua cadeia de ancestrais. Nos seguintes cenários:

  • a.com -> b.com
  • a.com -> b.com -> b.com
  • a.com -> a.com -> b.com
  • a.com -> b.com -> c.com

o uso de WebOTP em b.com é suportado, mas não em c.com.

Observe que o cenário a seguir também não é suportado devido à falta de demanda e às complexidades da UX.

  • a.com -> b.com -> a.com (chama a API WebOTP)

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.

Updated on Improve article

This site uses cookies to deliver and enhance the quality of its services and to analyze traffic. If you agree, cookies are also used to serve advertising and to personalize the content and advertisements that you see. Learn more about our use of cookies.