Prácticas recomendadas para el formulario de OTP de SMS

Obtén información para optimizar tu formulario de OTP por SMS y mejorar la experiencia del usuario.

Pedirle a un usuario que proporcione la OTP (contraseña de un solo uso) enviada por SMS es una forma común de confirmar el número de teléfono de un usuario. Existen algunos casos de uso para 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 claro de que la cuenta es propiedad de 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 el OTP recibido 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. Algunos métodos comunes de recuperación de la cuenta son el envío de 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.
  • Confirmación del pago: En los sistemas de pago, algunos bancos o entidades emisoras de tarjetas de crédito solicitan autenticación adicional al pagador por motivos de seguridad. Por lo general, las OTP por SMS se usan con ese fin.

En esta publicación, se explican las prácticas recomendadas para crear un formulario de OTP por SMS para los casos de uso anteriores.

Lista de tareas

Para brindar 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_CODE como ú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 las 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>

Las siguientes son 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 porque cambia el teclado del dispositivo móvil a solo números. Esto no se recomienda, ya que 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. El uso de type="number" hace que los botones de arriba y abajo se muestren junto al campo de entrada. Cuando se presionan, aumenta o disminuye el número, y es posible que se quiten los ceros anteriores.

Usa type="text" en su lugar. Esto no convertirá el teclado del dispositivo móvil en solo números, pero está bien porque la siguiente sugerencia para usar inputmode="numeric" hace ese trabajo.

inputmode="numeric"

Usa inputmode="numeric" para cambiar el teclado del dispositivo móvil a solo números.

Algunos sitios web usan type="tel" para los campos de entrada de OTP, ya que también convierte el teclado del dispositivo móvil en números únicamente (incluidos * y #) cuando se enfocan. Este hackeo se usó en el pasado cuando inputmode="numeric" no tenía ampliamente compatibilidad. Dado que Firefox comenzó a admitir inputmode="numeric", no es necesario usar el hackeo de type="tel" de forma semántica incorrecta.

autocomplete="one-time-code"

El atributo autocomplete permite a los desarrolladores especificar qué permiso tiene el navegador para proporcionar asistencia de autocompletado y le informa 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 analizará la OTP en el SMS de forma heurística, y el teclado sugerirá la OTP que el usuario debe ingresar. Solo funciona en Safari 12 y versiones posteriores en iOS, iPadOS y macOS, pero te recomendamos que lo uses, ya que es una forma fácil 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 asegurarte de que el mensaje SMS cumpla con el formato del mensaje vinculado al origen para realizar más acciones.

Cómo darle formato al texto de SMS

Mejora la experiencia del usuario a la hora de ingresar una OTP. Para ello, alinea los códigos únicos vinculados al origen que se entregan a través de SMS.

La regla de formato es simple: finaliza el mensaje SMS con el dominio del receptor precedido de @ y la OTP precedida de #.

Por ejemplo:

Your OTP is 123456

@web-otp.glitch.me #123456

El uso de un formato estándar para los mensajes de OTP hace que la extracción de códigos de ellos sea más fácil y confiable. Asociar códigos OTP a sitios web dificulta el engaño de los usuarios para que proporcionen un código a sitios maliciosos.

El uso de este formato ofrece algunas ventajas:

  • La OTP estará vinculada al dominio. Si el usuario se encuentra en dominios distintos del que se especificó en el mensaje SMS, no aparecerá la sugerencia de OTP. Esto también mitiga el riesgo de ataques de suplantación de identidad (phishing) y posibles usurpaciones de cuentas.
  • Ahora, el navegador podrá extraer la OTP de manera 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 que siga las reglas anteriores.

Este formato de mensaje SMS también es útil para otros navegadores aparte de Safari. Chrome, Opera y Vivaldi en Android también admiten la regla de códigos únicos 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. Si llamas a navigator.credentials.get() con el tipo otp (OTPCredential) donde transport incluye sms, el sitio web esperará a que el usuario entregue un SMS que cumpla con los códigos únicos vinculados al origen para que el usuario le otorgue acceso. Una vez que la OTP se pasa a JavaScript, el sitio web puede usarla como formulario o POST directamente en el servidor.

navigator.credentials.get({
  otp: {transport:['sms']}
})
.then(otp => input.value = otp.code);
API de WebOTP en acción.

Aprende a usar la API de WebOTP detalladamente en Cómo verificar los números de teléfono en la Web con la API de WebOTP o copia y pega el siguiente fragmento. (Asegúrate de que el elemento <form> tenga los atributos action y method configurados correctamente).

// 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);
    });
  });
}

Foto de Jason Leung en Unsplash.