Ayuda a los usuarios con OTP recibidos por SMS
¿Qué es la API de WebOTP?
En la actualidad, la mayoría de las personas en el mundo tienen un dispositivo móvil, y los desarrolladores suelen utilizar números de teléfono como identificador para los usuarios de sus servicios.
Existen varias formas de verificar números de teléfono, pero una contraseña de un solo uso (OTP) generada al azar que se envía por SMS es una de las más comunes. El envío de este código de vuelta al servidor del desarrollador demuestra el control del número de teléfono.
Esta idea ya se implementa en muchas situaciones para lograr lo siguiente:
- Número de teléfono como identificador del usuario. Cuando se registran para un servicio nuevo, algunos sitios web solicitan un número de teléfono en lugar de una dirección de correo electrónico y lo usan como identificador de cuenta.
- Verificación en dos pasos Cuando accedes, un sitio web solicita un código único 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 único que se envía por SMS puede ayudar a verificar su intención.
El proceso actual genera inconvenientes para los usuarios. Encontrar una OTP en un mensaje SMS y, luego, copiarla y pegarla en el formulario es engorroso, ya que disminuye los porcentajes de conversiones en los recorridos críticos del usuario. Facilitar esta ha sido una solicitud de larga data para la Web por parte de muchos de los desarrolladores globales más grandes. Android tiene una API que hace exactamente esto. iOS y Safari también.
La API de WebOTP permite que tu app reciba mensajes con formato especial vinculados al dominio de tu app. De esta manera, puedes obtener de manera programática una OTP a partir de un mensaje SMS y verificar el número de teléfono del usuario con más facilidad.
Observa cómo funciona
Supongamos que un usuario desea verificar su número de teléfono a través de un sitio web. El sitio web envía un mensaje de texto al usuario por SMS, y el usuario 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 presionar para el usuario, como se muestra en el video. Cuando llega el mensaje de texto, aparece una hoja inferior que le pide al usuario que verifique su número de teléfono. Después de hacer clic en el botón Verificar de la hoja inferior, el navegador pega la OTP en el formulario y se envía sin que el usuario tenga que presionar Continuar.
En la imagen de abajo, se muestra un diagrama de todo el proceso.
Prueba la demostración tú mismo. No se te solicita tu número de teléfono ni se 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 es el remitente cuando se usa la API de WebOTP.
- Ve a https://web-otp.glitch.me en Chrome 84 o una versión posterior en un dispositivo Android.
- Envía el siguiente mensaje de texto SMS a tu teléfono desde el otro teléfono.
Your OTP is: 123456.
@web-otp.glitch.me #12345
¿Recibiste el SMS y viste un mensaje para ingresar el código en el área de entrada? Así es como la API de WebOTP funciona para los usuarios.
El uso de la API de WebOTP consta de tres partes:
- Una etiqueta
<input>
anotada correctamente - JavaScript en tu app web
- Texto del mensaje con formato enviado por SMS.
Primero, explicaré la etiqueta <input>
.
Anota una etiqueta <input>
WebOTP funciona sin ninguna anotación HTML, pero para la compatibilidad entre navegadores, te recomendamos que agregues autocomplete="one-time-code"
a la etiqueta <input>
donde esperas que el usuario ingrese una OTP.
Esto permite que Safari 14 o versiones posteriores sugieran que el usuario complete el campo <input>
con una OTP cuando reciba un SMS con el formato que se describe en Da formato al mensaje SMS, aunque no sea compatible con WebOTP.
HTML
<form>
<input autocomplete="one-time-code" required/>
<input type="submit">
</form>
Usa la API de WebOTP
WebOTP es sencillo, solo puedes copiar y pegar el siguiente código. De todas formas, 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 funciones
La detección de funciones es la misma que para muchas otras APIs. Si escuchas el evento DOMContentLoaded
, se esperará a que el árbol del DOM esté listo para realizar consultas.
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 opción otp
nueva a ese método. Solo tiene una propiedad: transport
, cuyo valor debe ser un array con la string '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 que se muestra 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 que requiere que el usuario presione 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);
});
…
Anulando el mensaje
En caso de que el usuario ingrese manualmente una OTP y envíe el formulario, puedes cancelar la llamada a get()
mediante 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 => {
…
Da formato al mensaje SMS
La API en sí debería verse bastante simple, pero hay unas cuestiones que debes saber antes de usarla. El mensaje debe enviarse 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 tener el siguiente formato:
- El mensaje comienza con texto legible por humanos (opcional) que contiene una cadena alfanumérica de cuatro a diez caracteres en la que al menos un número sale de la última línea de 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 numeral ("
#
") seguido de la OTP.
Por ejemplo:
Your OTP is: 123456.
@www.example.com #123456
Estos son malos ejemplos:
Ejemplo de texto de SMS con errores de formato | Por qué no funcionará |
---|---|
Here is your code for @example.com #123456 |
@ debe ser el primer carácter de la última línea. |
Your code for @example.com is #123456 |
@ debe ser 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 hay 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://web-otp.glitch.me
También puedes bifurcarlo y crear tu versión: https://glitch.com/edit/#!/web-otp.
Cómo usar WebOTP desde un iframe de origen cruzado
Por lo general, para la confirmación del pago se ingresa una OTP de SMS a un iframe de origen cruzado, especialmente 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 solicita al usuario que verifique su número de teléfono para confirmar la compra rápidamente. bank.example
envía un SMS que contiene una OTP al usuario para que pueda ingresarla y verificar su identidad.
Para usar la API de WebOTP desde un iframe de origen cruzado, debes realizar dos acciones:
- Anota el origen del fotograma superior y el del iframe en el mensaje de texto SMS.
- Configura la política de permisos para permitir que el iframe de origen cruzado reciba la OTP directamente del usuario.
Puedes probar la demostración en https://web-otp-iframe-demo.stackblitz.io.
Anota los orígenes vinculados en el mensaje de texto SMS
Cuando se llama a la API de WebOTP desde un iframe, el mensaje de texto SMS debe incluir el origen del fotograma superior precedido por @
seguido de 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 WebOTP en un iframe de origen cruzado, el incorporador debe otorgar acceso a esta API mediante la política de permisos de credenciales otp-credentials para evitar comportamientos no deseados. En general, hay dos formas de lograr este objetivo:
a través del encabezado HTTP:
Permissions-Policy: otp-credentials=(self "https://bank.example")
mediante el atributo allow
de iframe:
<iframe src="https://bank.example/…" allow="otp-credentials"></iframe>
Consulta más ejemplos para especificar una política de permisos .
Usa WebOTP en una computadora
En Chrome, WebOTP admite la detección de SMS recibidos en otros dispositivos para ayudar a los usuarios a completar la verificación del número de teléfono en computadoras de escritorio.
Esta función requiere que el usuario acceda a la misma Cuenta de Google en Chrome para computadoras de escritorio y Android.
Todos los desarrolladores deben implementar la API de WebOTP en su sitio web para computadoras de escritorio, de la misma manera que en su sitio web móvil, pero no se requieren trucos especiales.
Obtén más información en Cómo verificar un número de teléfono en una computadora de escritorio con la API de WebOTP.
Preguntas frecuentes
El diálogo no aparece aunque envío un mensaje con el formato correcto. ¿Cuál es el problema?
Existen algunas advertencias a la hora de probar la API:
- Si el número de teléfono del remitente está incluido en la lista de contactos del destinatario, esta API no se activará debido al diseño de la API de SMS User Consent 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 el SMS tiene el formato correcto.
¿Esta API es compatible con distintos 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. Aunque Safari no admite la API de JavaScript de WebOTP, mediante la anotación del elemento input
con autocomplete=["one-time-code"]
, el teclado predeterminado sugiere 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 la 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 mediante SMS se debe usar con cuidado para la reautenticación, ya que los operadores pueden usurpar y reciclar los números de teléfono. WebOTP es un mecanismo conveniente de reautenticación y recuperación, pero los servicios deben combinarlo con factores adicionales, como un desafío de conocimiento, o usar la API de Web Authentication para lograr una autenticación sólida.
¿Dónde puedo informar errores de implementación de Chrome?
¿Encontraste un error en la implementación de Chrome?
- Informa un error en https://new.crbug.com. Incluye todos los detalles que puedas, instrucciones simples para reproducir el contenido y establece los Componentes en
Blink>WebOTP
.
¿Cómo puedo ayudar con esta función?
¿Piensas usar la API de WebOTP? Tu apoyo público nos ayuda a priorizar funciones y muestra a otros proveedores de navegadores lo fundamental 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 una computadora de escritorio con la API de WebOTP
- Cómo completar formularios de OTP dentro de iframes de origen cruzado con la API de WebOTP
- Centro de ayuda de Yahoo! La autenticación sin contraseñas de Japón redujo las consultas en un 25% y aceleró el tiempo de acceso 2.6 veces.