Ajudar os usuários com OTPs recebidos por SMS
O que é a API WebOTP?
Atualmente, a maioria das pessoas no mundo tem um dispositivo móvel, e os desenvolvedores geralmente usam números de telefone como identificador dos usuários dos serviços.
Há várias maneiras de verificar números de telefone, mas uma senha única (OTP, na sigla em inglês) 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.
Essa ideia já foi implantada em vários cenários para:
- Número de telefone como um identificador do usuário. Ao se inscrever em um novo serviço, alguns sites solicitam 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 solicita um código de uso único enviado por SMS, além de uma senha ou outro fator de conhecimento para maior segurança.
- Confirmação do pagamento. Quando um usuário está fazendo um pagamento, pedir 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 um OTP em uma mensagem de SMS e copiá-lo e colá-lo no formulário é complicado, reduzindo as taxas de conversão em jornadas de usuários importantes. A simplificação desse processo é uma solicitação antiga da Web feita por muitos dos maiores desenvolvedores do mundo. O Android tem uma API que faz exatamente isso. O iOS e o Safari também.
A API WebOTP permite que seu app receba mensagens formatadas de maneira especial vinculadas ao domínio do app. Com isso, é possível receber uma OTP de uma mensagem SMS e verificar um número de telefone do usuário com mais facilidade.
Confira na prática
Digamos que um usuário queira verificar o número de telefone em 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.
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 página inferior aparece e solicita que o usuário verifique o número de telefone. Depois de clicar no botão Verificar na página inferior, o navegador cola o OTP no formulário, e o formulário é enviado sem que o usuário precise pressionar Continuar.
O processo todo está diagramado na imagem abaixo.
Teste a demonstração. Ele não solicita seu número de telefone nem envia um SMS para seu dispositivo, mas você pode enviar um de outro dispositivo copiando o texto mostrado na demonstração. Isso funciona porque não importa quem é o remetente ao usar a API WebOTP.
- Acesse https://web-otp.glitch.me no Chrome 84 ou mais recente em um dispositivo Android.
- Envie a seguinte mensagem de texto SMS do outro smartphone para o seu.
Your OTP is: 123456.
@web-otp.glitch.me #12345
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>
devidamente anotada - JavaScript no seu app da Web
- Texto da mensagem formatada enviada por SMS.
Vou falar primeiro sobre a tag <input>
.
Anotar uma tag <input>
O WebOTP funciona sem nenhuma anotação HTML, mas, para compatibilidade entre navegadores, é altamente recomendável adicionar autocomplete="one-time-code"
à tag <input>
em que você espera que o usuário insira um OTP.
Isso permite que o Safari 14 ou mais recente sugira que o usuário preencha automaticamente o campo <input>
com um OTP quando receber um SMS com o formato descrito em Formatar a mensagem SMS, mesmo que não ofereça suporte ao WebOTP.
HTML
<form>
<input autocomplete="one-time-code" required/>
<input type="submit">
</form>
Usar a API WebOTP
Como o WebOTP é simples, basta copiar e colar o código abaixo. 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. A escuta do evento
DOMContentLoaded
vai aguardar a árvore DOM ficar pronta para 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');
…
});
}
Processar a OTP
A API WebOTP é bastante simples. Use
navigator.credentials.get()
para receber o OTP. O WebOTP adiciona uma nova opção otp
a esse método. Ele 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
recebido
{
code: "123456" // Obtained OTP
type: "otp" // `type` is always "otp"
}
Em seguida, transmita o valor do OTP para o campo <input>
. O envio direto do formulário
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);
});
…
Como abortar a mensagem
Caso o usuário insira manualmente um 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 => {
…
Formatar a mensagem de SMS
A API 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 chamada e precisa ser 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 por humanos (opcional) 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 cifrão ("
#
") seguido pelo OTP.
Exemplo:
Your OTP is: 123456.
@www.example.com #123456
Confira alguns exemplos ruins:
Exemplo de texto de SMS com formato incorreto | Por que isso 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 |
Um único espaço é esperado entre @host e #code . |
Your verification code is 123456 @example.com #123456 |
Um único espaço é esperado 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://web-otp.glitch.me
Você também pode bifurcar e criar sua versão: https://glitch.com/edit/#!/web-otp.
Usar o WebOTP em um iframe entre origens
A inserção de um OTP 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 envia OTPs vinculados a origens aninhadas. Por exemplo:
- Um usuário visita
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 finalizar a compra rapidamente. - O
bank.example
envia um SMS que contém um OTP para que o usuário possa digitá-lo para verificar a identidade.
Para usar a API WebOTP em um iframe de origem cruzada, você precisa fazer duas coisas:
- Faça anotações sobre a origem do frame superior e a origem do iframe na mensagem de texto do SMS.
- Configure a política de permissões para permitir que o iframe entre origens receba OTP diretamente do usuário.
Teste a demonstração em https://web-otp-iframe-demo.stackblitz.io.
Anotar origens vinculadas à mensagem de texto do SMS
Quando a API WebOTP é chamada em um iframe, a mensagem de texto SMS precisa
incluir a origem do frame superior 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 o WebOTP em um iframe de origem cruzada, o incorporador precisa conceder acesso a essa API pela política de permissões de credenciais de otp para evitar comportamentos inesperados. Em geral, há duas maneiras de alcançar esse objetivo:
Por cabeçalho HTTP:
Permissions-Policy: otp-credentials=(self "https://bank.example")
pelo atributo allow
do iframe:
<iframe src="https://bank.example/…" allow="otp-credentials"></iframe>
Confira mais exemplos sobre como especificar uma política de permissão .
Usar o WebOTP no computador
No Chrome, o WebOTP oferece suporte à detecção de SMSs recebidos em outros dispositivos para ajudar os usuários a concluir a verificação do número de telefone no computador.
Esse recurso exige que o usuário faça login na mesma Conta do Google no Chrome para computador e no Chrome para Android.
Tudo o que os desenvolvedores precisam fazer é implementar a API WebOTP no site para computador, da mesma forma que fazem no site para dispositivos móveis, mas sem 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, embora 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 SMS User Consent (consentimento do usuário do SMS, em tradução livre) subjacente.
- Se você estiver usando um perfil de trabalho no dispositivo Android e o WebOTP não funcionar, tente instalar e usar o Chrome no seu perfil pessoal (ou seja, o mesmo perfil em que você recebe mensagens SMS).
Verifique 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 partir do iOS 14
e do macOS Big Sur. Embora o Safari não ofereça suporte à 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 de SMS estiver
no formato correto.
É seguro usar o 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 de número de telefone por SMS precisa ser usada com cuidado para a re-autenticação, já que os números de telefone podem ser roubados e reciclados pelas operadoras. O WebOTP é um mecanismo conveniente de reautorização e recuperação, mas os serviços precisam combinar isso 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 Components como
Blink>WebOTP
.
Como posso ajudar esse recurso?
Você planeja usar a API WebOTP? Seu apoio público nos ajuda a priorizar
os 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 nos informe onde e como você está usando.