Ajudar os usuários com senhas únicas recebidas por SMS
O que é a API WebOTP?
Hoje em dia, a maioria das pessoas no mundo tem um dispositivo móvel, e os desenvolvedores costumam usar números de telefone como identificador dos usuários dos serviços deles.
Há várias maneiras de verificar números de telefone, mas uma senha única (OTP) gerada aleatoriamente e enviada por SMS é uma das mais comuns. Enviar esse código de volta ao servidor do desenvolvedor demonstra o controle do número de telefone.
Essa ideia já é implantada em muitos cenários para alcançar:
- Número de telefone como identificador do 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 único enviado por SMS, além de uma senha ou outro fator de conhecimento para mais segurança.
- Confirmação de pagamento. Quando um usuário está fazendo um pagamento, pedir um código único enviado por SMS pode ajudar a verificar a intenção da pessoa.
O processo atual cria atrito para os usuários. Encontrar um OTP em uma mensagem SMS, copiar e colar no formulário é complicado, o que reduz as taxas de conversão em jornadas críticas do usuário. Facilitar isso é uma solicitação antiga para a Web de muitos dos maiores desenvolvedores globais. O Android tem uma API que faz exatamente isso. O mesmo vale para o iOS e o Safari.
A API WebOTP permite que seu app receba mensagens formatadas especialmente vinculadas ao domínio dele. Assim, você pode receber uma OTP de uma mensagem SMS e verificar um número de telefone para o usuário com mais facilidade.
Veja na prática
Digamos que um usuário queira verificar o número de telefone dele com um site. O site envia uma mensagem de texto por SMS para o usuário, que insere o OTP da mensagem para verificar a propriedade do número de telefone.
Com a API WebOTP, essas etapas são tão fáceis quanto um toque para o usuário, conforme demonstrado no vídeo. Quando a mensagem de texto chega, uma caixa de diálogo aparece na parte de baixo e pede que o usuário verifique o número de telefone. Depois de clicar no botão Verificar na parte de baixo da tela, o navegador cola o OTP no formulário, que é enviado sem que o usuário precise pressionar Continuar.
Todo o processo está diagramado na imagem abaixo.

Teste a demonstração. Ele não pede seu número de telefone nem envia um SMS para seu dispositivo, mas você pode enviar um de outro dispositivo copiando o texto exibido na demonstração. Isso funciona porque não importa quem é o remetente ao usar a API WebOTP.
- Acesse https://chrome.dev/web-otp-demo no Chrome 84 ou em uma versão mais recente em um dispositivo Android.
- Envie para seu smartphone a seguinte mensagem de texto SMS de outro smartphone.
Your OTP is: 123456.
@chrome.dev #123456
Você recebeu o SMS e viu a solicitação 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>
anotada corretamente - JavaScript no seu app da Web
- Texto da mensagem formatada enviada por SMS.
Primeiro, vou falar sobre a tag <input>
.
Anotar uma tag <input>
A WebOTP funciona sem anotação HTML, mas para compatibilidade entre navegadores, recomendo adicionar autocomplete="one-time-code"
à tag <input>
onde você espera que o usuário insira uma senha única.
Isso permite que o Safari 14 ou versões mais recentes sugiram ao usuário o preenchimento automático do campo <input>
com uma senha única quando ele receber um SMS com o formato descrito em Formatar a mensagem SMS, mesmo que não seja compatível com a WebOTP.
HTML
<form>
<input autocomplete="one-time-code" required/>
<input type="submit">
</form>
Usar a API WebOTP
Como a WebOTP é simples, basta copiar e colar o código a seguir. Vou explicar 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 de muitas outras APIs. Ouvir o evento
DOMContentLoaded
aguardará que a árvore DOM esteja pronta para ser consultada.
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');
…
});
}
Processar a OTP
A API WebOTP em si é simples o suficiente. Use
navigator.credentials.get()
para receber o OTP. A WebOTP adiciona uma nova opção otp
a esse método. Ela tem apenas uma propriedade: transport
, cujo valor precisa ser uma matriz com a string 'sms'
.
JavaScript
…
navigator.credentials.get({
otp: { transport:['sms'] }
…
}).then(otp => {
…
Isso aciona o fluxo de permissão do navegador quando uma mensagem SMS chega. 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, transmita o valor do OTP para o campo <input>
. Enviar o formulário diretamente
elimina a etapa em que o usuário precisa tocar em um botão.
JavaScript
…
navigator.credentials.get({
otp: { transport:['sms'] }
…
}).then(otp => {
input.value = otp.code;
if (form) form.submit();
}).catch(err => {
console.error(err);
});
…
Abortar a mensagem
Caso o usuário insira manualmente um OTP e envie o formulário, você poderá 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 => {
…
Formatar a mensagem SMS
A API em si parece simples, mas há algumas coisas que você precisa saber antes de usá-la. A mensagem precisa ser enviada depois que
navigator.credentials.get()
for chamado e recebida no dispositivo
em que get()
foi chamado. Por fim, a mensagem precisa seguir a seguinte formatação:
- A mensagem começa com um texto legível que contém uma string alfanumérica de quatro a dez caracteres com pelo menos um número, deixando a última linha para o URL e o OTP.
- A parte do domínio do URL do site que invocou a API precisa ser precedida por
@
. - O URL precisa conter um sinal de libra ("
#
") seguido pelo OTP.
Exemplo:
Your OTP is: 123456.
@www.example.com #123456
Confira alguns exemplos ruins:
Exemplo de texto de SMS malformado | Por que isso não vai funcionar |
---|---|
Here is your code for @example.com #123456 |
Espera-se que @ seja o primeiro caractere da última linha. |
Your code for @example.com is #123456 |
Espera-se que @ seja o primeiro caractere da última linha. |
Your verification code is 123456 @example.com\t#123456 |
É esperado um único espaço entre @host e #code . |
Your verification code is 123456 @example.com #123456 |
É esperado 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 |
Não é possível incluir a porta. |
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 há espaços em branco no domínio. |
Your verification code is 123456 @domain-forbiden-chars-#%/:<>?@[] #123456 |
Não há 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 |
# ausente. |
Your verification code is 123456 example.com #123456 |
@ ausente. |
Hi mom, did you receive my last text |
@ e # ausentes. |
Demonstrações
Teste várias mensagens com a demonstração: https://chrome.dev/web-otp-demo
O código-fonte pode ser encontrado aqui: https://github.com/GoogleChromeLabs/web-identity-demos/tree/main/web-otp-demo.
Usar a WebOTP de um iframe entre origens
A inserção de uma senha única por SMS em um iframe de origem cruzada é normalmente usada para confirmação de pagamento, especialmente com o 3D Secure. Com o formato comum para oferecer suporte a iframes de origem cruzada, a API WebOTP entrega senhas únicas vinculadas a origens aninhadas. Por exemplo:
- Um usuário acessa
shop.example
para comprar um par de sapatos com um 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 de
bank.example
em um iframe pedindo que o usuário verifique o número de telefone para uma finalização de compra rápida. - O
bank.example
envia um SMS com um OTP para o usuário, que pode inseri-lo para verificar a identidade.
Para usar a API WebOTP em um iframe de origem cruzada, você precisa fazer duas coisas:
- Anotar a origem do frame principal e do iframe na mensagem de texto por SMS.
- Configure a política de permissões para permitir que o iframe de origem cruzada receba o OTP diretamente do usuário.
Teste a demonstração em https://web-otp-iframe-demo.stackblitz.io.
Anotar origens vinculadas na mensagem de texto por SMS
Quando a API WebOTP é chamada de um iframe, a mensagem de texto SMS precisa
incluir a origem do frame principal precedida por @
, seguida pelo OTP precedido por #
e a origem do iframe precedida por @
na última linha.
Your verification code is 123456
@shop.example #123456 @bank.exmple
Configurar a política de permissões
Para usar a WebOTP em um iframe de origem cruzada, o incorporador precisa conceder acesso a essa API usando uma política de permissões otp-credentials para evitar um comportamento indesejado. Em geral, há duas maneiras de alcançar essa meta:
via cabeçalho HTTP:
Permissions-Policy: otp-credentials=(self "https://bank.example")
usando o atributo allow
do iframe:
<iframe src="https://bank.example/…" allow="otp-credentials"></iframe>
Confira mais exemplos de como especificar uma política de permissões .
Usar a WebOTP no computador
No Chrome, a WebOTP oferece suporte à escuta de SMSs recebidos em outros dispositivos para ajudar os usuários a concluir a verificação do número de telefone no computador.
Para isso, o usuário precisa fazer login na mesma Conta do Google no Chrome para computador e no Chrome para Android.
Os desenvolvedores só precisam implementar a API WebOTP no site para computador da mesma forma que fazem no site para dispositivos móveis, sem precisar de truques especiais.
Saiba mais em Verificar um número de telefone no computador usando a API WebOTP.
Perguntas frequentes
A caixa de diálogo não aparece, mesmo que eu esteja enviando uma mensagem formatada corretamente. O que deu errado?
Há algumas ressalvas ao testar a API:
- Se o número de telefone do remetente estiver incluído na lista de contatos do destinatário, essa API não será acionada devido ao design da API de consentimento do usuário de SMS.
- Se você estiver usando um perfil de trabalho no dispositivo Android e o WebOTP não funcionar, instale e use o Chrome no seu perfil pessoal (ou seja, o mesmo perfil em que você recebe mensagens SMS).
Confira o formato para saber se o SMS está formatado corretamente.
Essa API é compatível com diferentes navegadores?
O Chromium e o WebKit concordaram com o formato de mensagem de texto SMS, e a Apple anunciou o suporte do Safari a ele a partir do iOS 14 e do macOS Big Sur. Embora o Safari não seja compatível com a API JavaScript 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 de acordo
com o formato.
É seguro usar SMS como forma de autenticação?
Embora a OTP por SMS seja útil para verificar um número de telefone quando ele é fornecido pela primeira vez, a verificação por SMS precisa ser usada com cuidado para a reautenticação, já que os números podem ser sequestrados e reciclados pelas operadoras. A WebOTP é um mecanismo conveniente de reautenticação e recuperação, mas os serviços precisam combiná-la com outros fatores, como um desafio de conhecimento, ou usar a API Web Authentication para uma autenticação forte.
Onde posso informar bugs na implementação do Chrome?
Você encontrou um bug na implementação do Chrome?
- Registre um bug em
crbug.com.
Inclua o máximo de detalhes possível, instruções simples para reprodução e
defina Componentes como
Blink>WebOTP
.
Como posso ajudar esse recurso?
Você planeja usar a API WebOTP? Seu apoio público nos ajuda a priorizar recursos e mostra a outros fornecedores de navegadores a importância de oferecer suporte a eles.
Envie um tweet para @ChromiumDev usando a hashtag
#WebOTP
e conte para nós onde e como você está usando.