За обновлениями можно следить в telegram-канале https://t.me/quasiart

СМС-код (или OTP — One Time Password) — распространённый и очень простой способ подтверждения операций в вебе, будь то аутентификация или подтверждение перевода денег.

Ввести короткий код из 4-6 символов для пользователя не составляет труда. Но даже это можно сделать за пользователя :-) Для этого существует WebOTP API.

Автоматическая вставка СМС в Android и Opera
Автоматическая вставка СМС в Android и Opera

Подсмотреть реализацию можно, например, при входе на какой-нибудь сайт с помощью Сбер ID.

Что нужно, чтобы реализовать на сайте автоматическую вставку СМС-кода:

  1. Изменить поле ввода СМС-кода (далее — просто «поле ввода»).
    1. Добавить type="text"
    2. Добавить inputmode="numeric"
    3. Добавить autocomplete="one-time-code"
  2. Изменить текст СМС.
    1. Последняя строчка без кавычек: «@foo.bar.com #12345»
  3. Использовать WebOTP API для большего контроля над вставкой СМС-кода.

Теперь о каждом пункте подробнее.

1 Изменить поле ввода СМС-кода

<input
    type="text"
    inputmode="numeric"
    autocomplete="one-time-code"
>

type="text"

Некоторые используют для поля ввода type="number", чтобы упростить реализацию валидации и чтобы на мобильных устройствах открывалась клавиатура в режиме ввода цифр. Но у этого с первого взгляда интуитивно правильного решения есть недостатки: у поля ввода появляются кнопки уменьшения и увеличения значения. Ну и семантически СМС-код — это последовательность цифр, в то время как input с type="number" служит для ввода числа.

inputmode="numeric"

Нужно для переключения клавиатуры в цифровой режим.

autocomplete="one-time-code"

Атрибут autocomplete информирует браузер о типе информации, ожидаемой в поле ввода.

С autocomplete="one-time-code" каждый раз, когда пользователь получает SMS-сообщение и форма открыта, операционная система анализирует OTP в тексте СМС, и клавиатура предлагает пользователю ввести OTP. Работает только в Safari 12 и более поздних версиях на iOS, iPadOS и macOS, но я рекомендую использовать это, поскольку это простой способ улучшить работу SMS OTP на этих платформах.

Демонстрация автовставки СМС-кода

2 Изменить текст СМС

Кратко правило выглядит так: последняя строка СМС должна содержать домен сайта, начинающийся на @, и OTP, начинающийся на #.

Пример СМС:

Для входа введите код 12345

@foo.bar.com #12345

Такая привязка OTP к адресу сайта затрудняет обман пользователей. Если в СМС указан один домен, а пользователь находится на другом, то механизм не сработает.

Подробно о форматировании СМС: https://wicg.github.io/sms-one-time-codes/

3 Использование WebOTP API

WebOTP API предоставляет доступ к OTP, которое мы получили по СМС. При вызове navigator.credentials.get() браузер будет ждать СМС. Как только OTP будет доступен в обработчике промиса (его возвращает метод get), можно будет использовать полученный OTP для вставки в поле.

navigator.credentials.get({
  otp: {transport:['sms']}
})
.then((otp) => input.value = otp.code)

Ещё советуют использовать AbortController, но мне это не помогло прервать появление системного UI вставки OTP.

Как тестировать

Демо: https://web-otp-demo.glitch.me

  1. Нужно убедиться, что в системе включена функция автоматической вставки СМС-кода.
  2. Я сначала пытался отправлять себе СМС с телефона другого человека: СМС приходили, но фича работала как-то нестабильно. Нашёл информацию, что номер телефона не должен быть в телефонной книге получателя. Толком не тестировал это.
  3. Для отправки СМС я использовал сервис sms.ru — он позволяет отправлять бесплатно СМС на свой номер.

Какие моменты стоит учесть

Учесть состояния, когда не нужно автоматически вставлять СМС-код:

  • Пользователь уже что-то вводит
  • Поле заблокировано (например, истекло время жизни СМС)

Проверяйте поддержку

Если вас заботит поддержка старых браузеров:

'OTPCredential' in window

Полезные ссылки

  1. https://developer.mozilla.org/en-US/docs/Web/API/WebOTP_API
  2. https://developer.chrome.com/articles/web-otp/
  3. https://web-otp-demo.glitch.me