СМС-код (или OTP — One Time Password) — распространённый и очень простой способ подтверждения операций в вебе, будь то аутентификация или подтверждение перевода денег.
Ввести короткий код из 4-6 символов для пользователя не составляет труда. Но даже это можно сделать за пользователя :-) Для этого существует WebOTP API.
Подсмотреть реализацию можно, например, при входе на какой-нибудь сайт с помощью Сбер ID.
Что нужно, чтобы реализовать на сайте автоматическую вставку СМС-кода:
- Изменить поле ввода СМС-кода (далее — просто «поле ввода»).
- Добавить type="text"
- Добавить inputmode="numeric"
- Добавить autocomplete="one-time-code"
- Изменить текст СМС.
- Последняя строчка без кавычек: «@foo.bar.com #12345»
- Использовать 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
- Нужно убедиться, что в системе включена функция автоматической вставки СМС-кода.
- Я сначала пытался отправлять себе СМС с телефона другого человека: СМС приходили, но фича работала как-то нестабильно. Нашёл информацию, что номер телефона не должен быть в телефонной книге получателя. Толком не тестировал это.
- Для отправки СМС я использовал сервис sms.ru — он позволяет отправлять бесплатно СМС на свой номер.
Какие моменты стоит учесть
Учесть состояния, когда не нужно автоматически вставлять СМС-код:
- Пользователь уже что-то вводит
- Поле заблокировано (например, истекло время жизни СМС)
Проверяйте поддержку
Если вас заботит поддержка старых браузеров:
'OTPCredential' in window