Ayuda a los usuarios con las OTP que reciben por SMS
¿Qué es la API de WebOTP?
Hoy en día, la mayoría de las personas en el mundo tienen un dispositivo móvil, y los desarrolladores suelen usar números de teléfono como identificadores de los usuarios de sus servicios.
Existen varias formas de verificar números de teléfono, pero una de las más comunes es una contraseña de un solo uso (OTP) generada de forma aleatoria y enviada por SMS. Enviar este código al servidor del desarrollador demuestra el control del número de teléfono.
Esta idea ya se implementó en muchas situaciones para lograr lo siguiente:
- Número de teléfono como identificador del usuario. Cuando te registras en un servicio nuevo, algunos sitios web te piden un número de teléfono en lugar de una dirección de correo electrónico y lo usan como identificador de la cuenta.
- Verificación en 2 pasos. Cuando accedes, un sitio web te pide un código de un solo uso que se envía por SMS, además de una contraseña o algún otro factor de conocimiento para mayor seguridad.
- Confirmación de pago. Cuando un usuario realiza un pago, solicitar un código de un solo uso enviado por SMS puede ayudar a verificar la intención de la persona.
El proceso actual genera fricción para los usuarios. Encontrar un OTP en un mensaje SMS y, luego, copiarlo y pegarlo en el formulario es engorroso, lo que reduce las tasas de conversión en los recorridos del usuario críticos. Aliviar esta situación ha sido una solicitud constante para la Web de muchos de los desarrolladores globales más grandes. Android tiene una API que hace exactamente esto. También lo hacen iOS y Safari.
La API de WebOTP permite que tu app reciba mensajes con un formato especial vinculados al dominio de tu app. De esta manera, puedes obtener de forma programática un OTP de un mensaje SMS y verificar el número de teléfono del usuario con mayor facilidad.
Observa cómo funciona
Supongamos que un usuario quiere verificar su número de teléfono con un sitio web. El sitio web envía un mensaje de texto al usuario por SMS, y este ingresa la OTP del mensaje para verificar la propiedad del número de teléfono.
Con la API de WebOTP, estos pasos son tan sencillos como un toque para el usuario, como se muestra en el video. Cuando llegue el mensaje de texto, aparecerá una hoja inferior que le pedirá al usuario que verifique su número de teléfono. Después de hacer clic en el botón Verificar en la hoja inferior, el navegador pega la OTP en el formulario y este se envía sin que el usuario tenga que presionar Continuar.
Todo el proceso se muestra en el siguiente diagrama.

Prueba la demostración. No te pide tu número de teléfono ni envía un SMS a tu dispositivo, pero puedes enviar uno desde otro dispositivo copiando el texto que se muestra en la demostración. Esto funciona porque no importa quién sea el remitente cuando se usa la API de WebOTP.
- Ve a https://chrome.dev/web-otp-demo en Chrome 84 o versiones posteriores en un dispositivo Android.
- Envía el siguiente SMS a tu teléfono desde otro teléfono.
Your OTP is: 123456.
@chrome.dev #123456
¿Recibiste el SMS y viste el mensaje para ingresar el código en el área de entrada? Así es como funciona la API de WebOTP para los usuarios.
El uso de la API de WebOTP consta de tres partes:
- Una etiqueta
<input>
anotada correctamente - JavaScript en tu app web
- Es el texto del mensaje con formato que se envía por SMS.
Primero, abordaré la etiqueta <input>
.
Cómo anotar una etiqueta <input>
WebOTP funciona sin ninguna anotación HTML, pero, para garantizar la compatibilidad entre navegadores, te recomiendo que agregues autocomplete="one-time-code"
a la etiqueta <input>
en la que esperas que el usuario ingrese una OTP.
Esto permite que Safari 14 o versiones posteriores sugieran al usuario que autocomplete el campo <input>
con una OTP cuando reciba un SMS con el formato descrito en Cómo dar formato al mensaje SMS, aunque no admita WebOTP.
HTML
<form>
<input autocomplete="one-time-code" required/>
<input type="submit">
</form>
Usa la API de WebOTP
Como WebOTP es simple, solo copiar y pegar el siguiente código será suficiente. De todos modos, te explicaré lo que sucede.
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);
});
});
}
Detección de características
La detección de funciones es la misma que para muchas otras APIs. Escuchar el evento DOMContentLoaded
esperará a que el árbol del DOM esté listo para la 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');
…
});
}
Procesa la OTP
La API de WebOTP en sí es bastante simple. Usa navigator.credentials.get()
para obtener la OTP. WebOTP agrega una nueva opción otp
a ese método. Solo tiene una propiedad: transport
, cuyo valor debe ser un array con la cadena 'sms'
.
JavaScript
…
navigator.credentials.get({
otp: { transport:['sms'] }
…
}).then(otp => {
…
Esto activa el flujo de permisos del navegador cuando llega un mensaje SMS. Si se otorga el permiso, la promesa devuelta se resuelve con un objeto OTPCredential
.
Contenido del objeto OTPCredential
obtenido
{
code: "123456" // Obtained OTP
type: "otp" // `type` is always "otp"
}
A continuación, pasa el valor de la OTP al campo <input>
. Si envías el formulario directamente, se eliminará el paso en el que el usuario debe presionar un botón.
JavaScript
…
navigator.credentials.get({
otp: { transport:['sms'] }
…
}).then(otp => {
input.value = otp.code;
if (form) form.submit();
}).catch(err => {
console.error(err);
});
…
Anulación del mensaje
En caso de que el usuario ingrese un OTP de forma manual y envíe el formulario, puedes cancelar la llamada de get()
con una instancia de AbortController
en el 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 => {
…
Cómo dar formato al mensaje SMS
La API en sí debería parecer bastante simple, pero hay algunas cosas que debes saber antes de usarla. El mensaje se debe enviar después de que se llame a navigator.credentials.get()
y se debe recibir en el dispositivo en el que se llamó a get()
. Por último, el mensaje debe cumplir con el siguiente formato:
- El mensaje comienza con texto legible para las personas que contiene una cadena alfanumérica de entre cuatro y diez caracteres con al menos un número, y deja la última línea para la URL y la OTP.
- La parte del dominio de la URL del sitio web que invocó la API debe estar precedida por
@
. - La URL debe contener un signo de número ('
#
') seguido del OTP.
Por ejemplo:
Your OTP is: 123456.
@www.example.com #123456
Estos son algunos ejemplos de imágenes de mala calidad:
Ejemplo de texto de SMS con formato incorrecto | Por qué no funcionará |
---|---|
Here is your code for @example.com #123456 |
Se espera que @ sea el primer carácter de la última línea. |
Your code for @example.com is #123456 |
Se espera que @ sea el primer carácter de la última línea. |
Your verification code is 123456 @example.com\t#123456 |
Se espera un solo espacio entre @host y #code . |
Your verification code is 123456 @example.com #123456 |
Se espera un solo espacio entre @host y #code . |
Your verification code is 123456 @ftp://example.com #123456 |
No se puede incluir el esquema de URL. |
Your verification code is 123456 @https://example.com #123456 |
No se puede incluir el esquema de URL. |
Your verification code is 123456 @example.com:8080 #123456 |
No se puede incluir el puerto. |
Your verification code is 123456 @example.com/foobar #123456 |
No se puede incluir la ruta de acceso. |
Your verification code is 123456 @example .com #123456 |
No debe haber espacios en blanco en el dominio. |
Your verification code is 123456 @domain-forbiden-chars-#%/:<>?@[] #123456 |
No hay caracteres prohibidos en el dominio. |
@example.com #123456 Mambo Jumbo |
Se espera que @host y #code sean la última línea. |
@example.com #123456 App hash #oudf08lkjsdf834 |
Se espera que @host y #code sean la última línea. |
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 text |
Faltan @ y # . |
Demostraciones
Prueba varios mensajes con la demostración: https://chrome.dev/web-otp-demo
Puedes encontrar el código fuente aquí: https://github.com/GoogleChromeLabs/web-identity-demos/tree/main/web-otp-demo.
Cómo usar WebOTP desde un iframe de origen cruzado
Por lo general, se ingresa una OTP por SMS en un iframe de origen cruzado para confirmar el pago, en especial con 3D Secure. Con el formato común para admitir iframes de origen cruzado, la API de WebOTP entrega OTP vinculadas a orígenes anidados. Por ejemplo:
- Un usuario visita
shop.example
para comprar un par de zapatos con una tarjeta de crédito. - Después de ingresar el número de tarjeta de crédito, el proveedor de pagos integrado muestra un formulario de
bank.example
dentro de un iframe en el que se le pide al usuario que verifique su número de teléfono para realizar una compra rápida. bank.example
envía un SMS que contiene un OTP al usuario para que lo ingrese y verifique su identidad.
Para usar la API de WebOTP desde un iframe de origen cruzado, debes hacer dos cosas:
- Anota el origen del frame superior y el origen del iframe en el mensaje de texto SMS.
- Configura la política de permisos para permitir que el iframe de origen cruzado reciba el OTP del usuario directamente.
Puedes probar la demostración en https://web-otp-iframe-demo.stackblitz.io.
Anota los orígenes vinculados al mensaje de texto por SMS
Cuando se llama a la API de WebOTP desde un iframe, el mensaje de texto SMS debe incluir el origen del marco superior precedido por @
, seguido por la OTP precedida por #
y el origen del iframe precedido por @
en la última línea.
Your verification code is 123456
@shop.example #123456 @bank.exmple
Configura la Política de permisos
Para usar la API de WebOTP en un iframe de origen cruzado, el incorporador debe otorgar acceso a esta API a través de la política de permisos de otp-credentials para evitar un comportamiento no deseado. En general, existen dos formas de lograr este objetivo:
A través del encabezado HTTP:
Permissions-Policy: otp-credentials=(self "https://bank.example")
A través del atributo allow
del iframe:
<iframe src="https://bank.example/…" allow="otp-credentials"></iframe>
Consulta más ejemplos para especificar una política de permisos .
Cómo usar WebOTP en computadoras
En Chrome, WebOTP admite la escucha de SMS recibidos en otros dispositivos para ayudar a los usuarios a completar la verificación del número de teléfono en computadoras.
Esta función requiere que el usuario acceda a la misma Cuenta de Google en Chrome para computadoras y Chrome para Android.
Lo único que deben hacer los desarrolladores es implementar la API de WebOTP en su sitio web para computadoras, de la misma manera que lo hacen en su sitio web para dispositivos móviles, pero no se requieren trucos especiales.
Obtén más detalles en Cómo verificar un número de teléfono en computadoras con la API de WebOTP.
Preguntas frecuentes
No aparece el diálogo, aunque envío un mensaje con el formato correcto. ¿Cuál es el problema?
Ten en cuenta algunas advertencias cuando pruebes la API:
- Si el número de teléfono del remitente se incluye en la lista de contactos del destinatario, no se activará esta API debido al diseño de la API de consentimiento del usuario para SMS subyacente.
- Si usas un perfil de trabajo en tu dispositivo Android y WebOTP no funciona, intenta instalar y usar Chrome en tu perfil personal (es decir, el mismo perfil en el que recibes mensajes SMS).
Vuelve a consultar el formato para ver si tu SMS tiene el formato correcto.
¿Esta API es compatible con diferentes navegadores?
Chromium y WebKit acordaron el formato de los mensajes de texto SMS, y Apple anunció la compatibilidad de Safari con él a partir de iOS 14 y macOS Big Sur. Si bien Safari no admite la API de WebOTP JavaScript, si anotas el elemento input
con autocomplete=["one-time-code"]
, el teclado predeterminado sugerirá automáticamente que ingreses la OTP si el mensaje SMS cumple con el formato.
¿Es seguro usar SMS como método de autenticación?
Si bien el OTP por SMS es útil para verificar un número de teléfono cuando se proporciona por primera vez, la verificación del número de teléfono por SMS se debe usar con cuidado para la reautenticación, ya que los operadores pueden secuestrar y reciclar los números de teléfono. WebOTP es un mecanismo conveniente de recuperación y reautenticación, pero los servicios deben combinarlo con factores adicionales, como un desafío de conocimiento, o usar la API de Web Authentication para una autenticación sólida.
¿Dónde puedo informar errores en la implementación de Chrome?
¿Encontraste un error en la implementación de Chrome?
- Informa un error en crbug.com. Incluye la mayor cantidad de detalles posible, instrucciones sencillas para reproducir el error y establece Components en
Blink>WebOTP
.
¿Cómo puedo ayudar a mejorar esta función?
¿Planeas usar la API de WebOTP? Tu apoyo público nos ayuda a priorizar funciones y les muestra a otros proveedores de navegadores lo importante que es admitirlas.
Envía un tweet a @ChromiumDev con el hashtag #WebOTP
y cuéntanos dónde y cómo lo usas.
Recursos
- Prácticas recomendadas para el formulario de OTP por SMS
- Cómo verificar un número de teléfono en computadoras con la API de WebOTP
- Cómo completar formularios de OTP en elementos iframe de varios orígenes con la API de WebOTP
- Yahoo! JAPÓN disminuyó las consultas en un 25% y aceleró el tiempo de acceso 2.6 veces