Es común pedirle a un usuario que proporcione una contraseña de un solo uso (OTP) para confirmar su identidad a través de un SMS. Estos son algunos casos de uso de las OTP por SMS:
- Autenticación de dos factores Además del nombre de usuario y la contraseña, la OTP por SMS se puede usar como un indicador sólido de que la cuenta pertenece a la persona que recibió la OTP por SMS.
- Verificación del número de teléfono Algunos servicios usan un número de teléfono como identificador principal del usuario. En estos servicios, los usuarios pueden ingresar su número de teléfono y la OTP que recibieron por SMS para demostrar su identidad. A veces, se combina con un PIN para constituir una autenticación de dos factores.
- Recuperación de la cuenta Cuando un usuario pierde el acceso a su cuenta, debe haber una forma de recuperarla. Enviar un correo electrónico a su dirección de correo electrónico registrada o una OTP por SMS a su número de teléfono son métodos comunes de recuperación de la cuenta.
- Confirmación de pago En los sistemas de pago, algunos bancos o entidades emisoras de tarjetas de crédito solicitan autenticación adicional del pagador por motivos de seguridad. Las OTP por SMS se suelen usar para ese propósito.
Sigue leyendo para conocer las prácticas recomendadas para crear formularios de OTP por SMS para estos casos de uso.
Lista de tareas
Para proporcionar la mejor experiencia del usuario con la OTP por SMS, sigue estos pasos:
- Usa el elemento
<input>con lo siguiente:type="text"inputmode="numeric"autocomplete="one-time-code"
- Usa
@BOUND_DOMAIN #OTP_CODEcomo la última línea del mensaje SMS de OTP. - Usa la API de WebOTP.
Usa el elemento <input>
Usar un formulario con un elemento <input> es la práctica recomendada más importante que puedes seguir, ya que funciona en todos los navegadores. Incluso si otras sugerencias de esta publicación no funcionan en algún navegador, el usuario podrá ingresar y enviar la OTP de forma manual.
<form action="/verify-otp" method="POST">
<input type="text"
inputmode="numeric"
autocomplete="one-time-code"
pattern="\d{6}"
required>
</form>
A continuación, se incluyen algunas ideas para garantizar que un campo de entrada aproveche al máximo la funcionalidad del navegador.
type="text"
Dado que las OTP suelen ser números de cinco o seis dígitos, usar type="number" para un campo de entrada puede parecer intuitivo, ya que cambia el teclado del dispositivo móvil solo a números. No se recomienda esta opción porque el navegador espera que un campo de entrada sea un número contable, en lugar de una secuencia de varios números, lo que puede causar un comportamiento inesperado. Si usas type="number", se mostrarán botones hacia arriba y hacia abajo junto al campo de entrada. Si presionas estos botones, se incrementará o disminuirá el número, y es posible que se quiten los ceros anteriores.
Usa type="text" en su lugar. Esto no convertirá el teclado para dispositivos móviles en solo números, pero está bien, ya que la siguiente sugerencia para usar inputmode="numeric" hace ese trabajo.
inputmode="numeric"
Usa inputmode="numeric"
para cambiar el teclado del dispositivo móvil solo a números.
Algunos sitios web usan type="tel" para los campos de entrada de OTP, ya que también
cambia el teclado del dispositivo móvil solo a números (incluidos * y #) cuando
se enfoca. Este truco se usaba en el pasado, cuando inputmode="numeric" no era ampliamente compatible. Como Firefox comenzó a admitir inputmode="numeric", no es necesario usar el hack type="tel", que es semánticamente incorrecto.
autocomplete="one-time-code"
El atributo autocomplete permite que los desarrolladores especifiquen qué permiso tiene el navegador para proporcionar asistencia de autocompletado y le informa al navegador sobre el tipo de información que se espera en el campo.
Con autocomplete="one-time-code", cada vez que un usuario recibe un mensaje SMS mientras un formulario está abierto, el sistema operativo analiza la OTP en el SMS de forma heurística y el teclado sugiere la OTP para que el usuario la ingrese. Solo funciona en Safari 12 y
versiones posteriores en iOS, iPadOS y macOS, pero te recomendamos que lo uses, ya que es
una mejor manera de mejorar la experiencia de OTP por SMS en esas plataformas.
autocomplete="one-time-code" en acción.
autocomplete="one-time-code" mejora la experiencia del usuario, pero puedes hacer más si te aseguras de que el mensaje SMS cumpla con el formato de mensaje vinculado al origen.
Atributos opcionales
Entre los atributos opcionales, se incluyen los siguientes:
patternespecifica el formato con el que debe coincidir la OTP ingresada. Usa expresiones regulares para especificar el patrón de coincidencia. Por ejemplo,\d{6}restringe la OTP a una cadena de seis dígitos. Lee Usa JavaScript para una validación en tiempo real más compleja para obtener más información sobrepattern.requiredindica que un usuario debe completar el campo.
Lee nuestras prácticas recomendadas para formularios de acceso para obtener más consejos.
Cómo dar formato al texto de los SMS
Mejora la experiencia del usuario cuando ingresa una OTP alineándote con la especificación de códigos de un solo uso vinculados al origen que se envían por SMS.
En esencia, la regla de formato es la siguiente: Termina el mensaje SMS con el dominio del receptor precedido por @ y la OTP precedida por #.
Por ejemplo:
Your OTP is 123456
@web-otp.example.com #123456
El formato estándar de los mensajes de OTP facilita la extracción y la hace más confiable. Asociar códigos OTP con sitios web hace que sea más difícil engañar a los usuarios para que proporcionen un código a sitios maliciosos.
Reglas de formato precisas
Las reglas precisas son las siguientes:
- El mensaje comienza con un texto legible por humanos (opcional) que contiene una cadena alfanumérica de cuatro a 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
#, seguido de la OTP. La cantidad de caracteres debe ser de 140 o menos.
Usar este formato ofrece un par de beneficios:
- La OTP se vinculará al dominio. Si el usuario se encuentra en dominios que no sean el especificado en el mensaje SMS, no aparecerá la sugerencia de OTP. Esto también mitiga el riesgo de ataques de phishing y posibles secuestros de cuentas.
- Ahora, el navegador podrá extraer la OTP de forma confiable sin depender de heurísticas misteriosas y poco confiables.
Cuando un sitio web usa autocomplete="one-time-code", Safari con iOS 14 o versiones posteriores
sugerirá la OTP según estas reglas.
Este formato de mensaje SMS también beneficia a otros navegadores además de Safari. Chrome, Opera y Vivaldi en Android también admiten la regla de códigos de un solo uso vinculados al origen con la API de WebOTP, aunque no a través de autocomplete="one-time-code".
Usa la API de WebOTP
La API de WebOTP proporciona acceso a la OTP
recibida en un mensaje SMS. Cuando se llama a navigator.credentials.get() con el tipo otp (OTPCredential), en el que transport incluye sms, el sitio web esperará a que se entregue un SMS que cumpla con los códigos de un solo uso vinculados al origen y que el usuario otorgue acceso. Una vez que la OTP se pasa a JavaScript,
el sitio web puede usarla en un formulario o enviarla directamente al servidor con POST.
navigator.credentials.get({
otp: {transport:['sms']}
})
.then(otp => input.value = otp.code);
Obtén información detallada para usar la API de WebOTP en Verifica números de teléfono en la Web con la API de WebOTP o copia y pega el siguiente fragmento. Asegúrate de establecer un atributo action y
method en tu <form>.
// Feature detection
if ('OTPCredential' in window) {
window.addEventListener('DOMContentLoaded', e => {
const input = document.querySelector('input[autocomplete="one-time-code"]');
if (!input) return;
// Cancel the WebOTP API if the form is submitted manually.
const ac = new AbortController();
const form = input.closest('form');
if (form) {
form.addEventListener('submit', e => {
// Cancel the WebOTP API.
ac.abort();
});
}
// Invoke the WebOTP API
navigator.credentials.get({
otp: { transport:['sms'] },
signal: ac.signal
}).then(otp => {
input.value = otp.code;
// Automatically submit the form when an OTP is obtained.
if (form) form.submit();
}).catch(err => {
console.log(err);
});
});
}