Автоподстановка OTP из SMS: форматы для Android, iOS и веба
Как работает автоподстановка OTP на Android, iOS и в вебе: хеш SMS Retriever, коды с привязкой к домену, WebOTP, единый формат SMS для трёх платформ и WhatsApp.
Автор: OmniChannels.ai Editorial Team · Проверил: BroadNet Messaging Solutions Team
Интеграции
Короткий ответ
Автоподстановка OTP строится из трёх независимых механизмов. Android-приложения используют SMS Retriever API, которому нужен 11-символьный хеш приложения в сообщении не длиннее 140 байт, либо SMS User Consent API без хеша. iOS предлагает код из самого SMS, а коды с привязкой к домену заканчиваются строкой вроде @example.com #123456. Сайты используют autocomplete="one-time-code" и WebOTP API, которые читают ту же последнюю строку.
На этой странице
- Как работает автоподстановка OTP на каждой платформе?
- Как работает SMS Retriever API на Android?
- Как iOS и iPadOS подставляют код?
- Как работает автоподстановка OTP в вебе?
- Может ли одно SMS работать на Android, iOS и в вебе?
- Что с арабским текстом и Unicode?
- Как шаблоны аутентификации WhatsApp справляются с автоподстановкой?
- Пример: вход в приложение такси
- Какие ошибки встречаются чаще всего?
- Чем помогает OmniChannels.ai
Главное
- На Android есть два API: SMS Retriever (сообщение не длиннее 140 байт с одноразовым кодом и 11-символьным хешем приложения) и SMS User Consent (пользователь разрешает передать приложению одно сообщение).
- На iOS задайте полю тип содержимого one-time-code; коды с привязкой к домену заканчиваются строкой из @домена, пробела и #кода, поддержка начинается с iOS 14.
- В вебе добавьте в поле autocomplete="one-time-code" и вызовите navigator.credentials.get с транспортом sms для Chrome на Android; Safari использует атрибут.
- Одно сообщение может подойти всем трём платформам, если хеш приложения стоит выше последней строки @домен #код, но проверьте это на реальных устройствах и у операторов.
- Шаблоны аутентификации WhatsApp дают кнопки копирования кода, one-tap и zero-tap; zero-tap работает только на Android.
Это руководство для разработчиков и владельцев продуктов, которые хотят, чтобы код подтверждения подставлялся сам на Android, iPhone и в вебе. В нём объясняется, что каждая платформа требует от SMS, как написать одно сообщение для всех трёх, как с автоподстановкой справляются шаблоны аутентификации WhatsApp и что чаще всего ломается.
Как работает автоподстановка OTP на каждой платформе?
Каждая платформа читает SMS по-своему, поэтому единого переключателя нет. Android требует либо хеш приложения, либо согласие пользователя, iOS сама распознаёт коды, а браузеры читают специально оформленную последнюю строку.
| Платформа | Механизм | Что нужно в SMS | Действие пользователя |
|---|---|---|---|
| Приложение Android | SMS Retriever API | Не более 140 байт, одноразовый код и 11-символьный хеш приложения | Не требуется |
| Приложение Android | SMS User Consent API | Сообщение с одноразовым кодом | Разрешает передать одно сообщение |
| Приложение iOS и iPadOS | Автозаполнение кода безопасности | Код, который iOS может распознать; рекомендуется формат с привязкой к домену | Нажимает на подсказку |
| Веб (Safari) | autocomplete="one-time-code" |
Последняя строка с привязкой к домену | Нажимает на подсказку |
| Веб (Chrome на Android) | WebOTP API | Последняя строка @host #code |
Подтверждает запрос |
Всё это помогает, только если SMS дошло. Если нет, см. OTP не приходит.
Как работает SMS Retriever API на Android?
Ваше приложение просит сервисы Google Play прослушать одно сообщение, а в сообщении есть хеш, идентифицирующий приложение. Дополнительных разрешений приложению не нужно.
В документации Google перечислены три требования к проверочному сообщению. Оно должно:
- быть не длиннее 140 байт;
- содержать одноразовый код, который приложение отправляет обратно на ваш сервер для завершения проверки;
- включать 11-символьную строку-хеш, идентифицирующую приложение.
Всё остальное в сообщении — на ваше усмотрение. Порядок такой: приложение запускает API, пока запрашивает SMS, ваш сервер отправляет сообщение, сервисы Play направляют его приложению, а приложение извлекает код и возвращает его серверу для проверки. Сервер также должен убедиться, что код действителен и не просрочен.
Как получить 11-символьный хеш?
По словам Google, хеш — это первые 11 символов хеша в кодировке base64. Он вычисляется из сертификата подписи приложения по шагам с keytool из документации Google. Если подписью приложения управляет Google Play, импортируйте этот сертификат для расчёта. Если вы подписываете сами, используйте продуктовое хранилище ключей и псевдоним сертификата.
Поскольку хеш зависит от сертификата подписи, сборка, подписанная другим ключом, получит другой хеш. Учитывайте это, когда проверяете отладочные сборки на боевых сообщениях, и подтверждайте хеш для каждой конфигурации подписи, которую выпускаете.
А если не хочется управлять хешем?
Используйте SMS User Consent API. По документации Google, перед передачей сообщения пользователя спрашивают, после чего всё сообщение становится доступно приложению, которое само выделяет код. Согласно странице Google, в сообщении должна быть буквенно-цифровая строка из 4–10 символов хотя бы с одной цифрой, прослушивание длится пять минут, а при желании можно ограничить отправителя. Запускайте API до прихода SMS: ранее полученные сообщения не передаются.
Как iOS и iPadOS подставляют код?
iOS распознаёт SMS с одноразовым кодом и предлагает его в полях, объявленных как поля для кода. Apple описывает для вас два шага.
- Задайте тип содержимого поля. В UIKit установите
textContentTypeв.oneTimeCode. В SwiftUI используйте модификаторtextContentTypeс тем же значением. Для сайта задайте у поляautocomplete="one-time-code". - При желании привяжите код к своему домену. Начиная с iOS 14 и macOS Big Sur Apple позволяет оформить SMS так, чтобы автозаполнение предлагало код, только если сайт в Safari или связанный домен приложения совпадает. Так труднее обманом заставить человека ввести код на фишинговом сайте.
Формат по Apple: сначала любой текст, затем последняя строка с вашим доменом с префиксом @, пробелом и кодом с префиксом #.
Your Example code is 123456.
@example.com #123456
Для приложения добавьте привязанный домен в связанные домены приложения, иначе автозаполнение не предложит код. Обычные коды без привязки по-прежнему распознаются, но Apple рекомендует формат с привязкой к домену.
Как работает автоподстановка OTP в вебе?
Сначала добавьте атрибут, затем JavaScript для браузеров, которые его поддерживают.
<input type="text" inputmode="numeric"
autocomplete="one-time-code" name="otp" />
Документация Chrome рекомендует атрибут для кросс-браузерной совместимости и сообщает, что Safari использует его, чтобы предлагать код из правильно оформленного SMS, хотя JavaScript API WebOTP в нём нет.
Для Chrome на Android вызовите WebOTP с транспортом sms. API требует защищённого источника (HTTPS), а AbortController позволяет отменить ожидающий запрос, если пользователь введёт код вручную.
if ("OTPCredential" in window) {
const ac = new AbortController();
const form = document.querySelector("form");
const input = document.querySelector("input[autocomplete=one-time-code]");
form.addEventListener("submit", () => ac.abort());
navigator.credentials
.get({ otp: { transport: ["sms"] }, signal: ac.signal })
.then((otp) => {
input.value = otp.code;
form.submit();
})
.catch(() => {}); // user dismissed, or no matching SMS
}
SMS должно следовать формату с привязкой к источнику из спецификации WICG и руководства Chrome: код из четырёх–десяти буквенно-цифровых символов хотя бы с одной цифрой перед последней строкой, затем последняя строка, начинающаяся с @, хоста, одного пробела и # с кодом. В хосте не должно быть пробельных символов.
Может ли одно SMS работать на Android, iOS и в вебе?
Часто да, потому что правила совместимы. Поставьте читаемый текст первым, хеш для Android в строку выше конца, а строку с привязкой к домену — последней. Эта схема собрана из документированных правил, а не гарантирована производителем, поэтому протестируйте её.
Your Example code is 483921. Do not share it.
Ab3dE+9xYz1
@example.com #483921
Почему такой порядок: и Apple, и спецификация веба хотят видеть домен и код в последней строке. Google требует 11-символьный хеш где-либо в сообщении, но на проверенной нами странице положение хеша не фиксирует. Пример выше занимает 78 байт простых латинских символов, что с запасом укладывается в лимит 140 байт.
Чек-лист перед запуском:
- Код — один токен, чётко отделённый от других цифр в тексте.
- Домен в последней строке совпадает с сайтом и связанным доменом приложения.
- Общая длина для варианта Retriever укладывается в 140 байт.
- Хеш соответствует ключу подписи тестируемой сборки.
- Проверено на телефоне каждой платформы у операторов, через которых вы реально отправляете.
Что с арабским текстом и Unicode?
Оставляйте код и две машиночитаемые части простыми. Лимит Google задан в байтах, а в Unicode-SMS помещается гораздо меньше символов, чем в GSM-7: 70 против 160 в одном сегменте (см. лимиты символов SMS и Unicode). Поэтому арабская фраза быстро съедает бюджет, а один символ вне GSM переводит всё сообщение в Unicode.
Надёжный подход: код пишите латинскими цифрами, @domain #code оставляйте в ASCII, а арабский текст делайте коротким. Официальной документации об автоподстановке кодов, записанных в других системах цифр, мы не нашли, поэтому не касаемся этого и рекомендуем протестировать перед использованием.
Как шаблоны аутентификации WhatsApp справляются с автоподстановкой?
Шаблоны аутентификации Meta имеют три стиля кнопок, у каждого фиксированный текст тела вида <code> is your verification code.
| Кнопка | Что делает | Примечания |
|---|---|---|
| Копирование кода | Пользователь нажимает, чтобы скопировать код, и вставляет его в ваше приложение | Работает без изменений в приложении |
| Автозаполнение one-tap | На Android кнопка открывает ваше приложение и передаёт код | Нужны package_name и signature_hash в supported_apps |
| Zero-tap | Кнопки нет; клиент WhatsApp передаёт код вашему приложению широковещательно | Только Android; нужно принять условия zero-tap от Meta |
В документации Meta также отмечено, что в iOS 26 и новее подсказки клавиатуры дают автозаполнение без интеграции, а пользователи платформ без zero-tap получают кнопку копирования кода. Срок действия можно задать через code_expiration_minutes, а API предпросмотра принимает значения от 1 до 90 минут. Сравнение каналов — в статье OTP в WhatsApp или в SMS.
Пример: вход в приложение такси
У «Qafila Rides» (вымышленный пример) есть приложение для Android, приложение для iOS и мобильный сайт qafila.example.
- Android-приложение запускает SMS Retriever, когда пользователь нажимает «Отправить код».
- Бэкенд генерирует шестизначный код со сроком действия в несколько минут и отправляет трёхстрочное сообщение выше через SMS API.
- Android передаёт сообщение приложению. iOS предлагает код над клавиатурой. На мобильном сайте Safari подсказывает его, а Chrome подставляет через WebOTP.
- Сервер проверяет код один раз, отклоняет повторное использование и просроченные коды и ограничивает частоту запросов.
- Если SMS не подтверждено за короткое время, бэкенд предлагает шаблон аутентификации WhatsApp как второй путь.
Какие ошибки встречаются чаще всего?
- Код не сам по себе. Лишние числа (телефон, цена, дата) рядом с кодом сбивают распознавание. Используйте один код на сообщение.
- Неверный хеш. Хеш следует за сертификатом подписи. Хеш отладочного ключа не подойдёт для боевой сборки.
- Несовпадение домена.
@example.comдолжен совпадать с сайтом или связанным доменом, иначе iOS и WebOTP не предложат код. - Сломанная последняя строка. Любой текст после
#code, отсутствующий пробел или пробельные символы внутри домена ломают формат. - Слишком длинное сообщение или много Unicode, что превышает лимит Retriever в 140 байт.
- Слишком позднее прослушивание. User Consent API игнорирует сообщения, полученные до запуска.
- Автоподстановка как защита. Автоподстановка — это удобство. По-прежнему проверяйте код на сервере, ограничивайте срок действия и число попыток и следите за мошенничеством с накруткой SMS.
- Границы статьи. Руководство описывает документированное поведение на момент написания. Правила платформ меняются, поэтому перед релизом сверяйтесь с источниками по ссылкам.
О формулировках сообщений и выборе срока действия см. руководство по OTP и аутентификационным сообщениям.
Чем помогает OmniChannels.ai
OmniChannels.ai отправляет OTP по SMS и WhatsApp через прямые подключения BroadNet к операторам, так что вы контролируете точный текст сообщения, от которого зависит ваш формат автоподстановки. Шаблоны WhatsApp охватывают аутентификацию с копированием кода, one-tap и zero-tap. Резервирование каналов, например WhatsApp, затем SMS, настраивается для каждого сценария, а статусы доставки приходят в одном формате вебхука. См. документацию SMS API, документацию WhatsApp API и решение для OTP.
Часто задаваемые вопросы
Каков формат сообщения для SMS Retriever API?
По документации Google, сообщение должно быть не длиннее 140 байт, содержать одноразовый код, который приложение отправляет обратно на ваш сервер, и включать 11-символьный хеш, идентифицирующий приложение. Остальное содержимое — на ваше усмотрение. Хеш позволяет сервисам Google Play направить сообщение нужному приложению без дополнительных разрешений.
Нужен ли хеш приложения для SMS User Consent API?
В обзоре SMS User Consent API от Google хеш приложения не описан. Вместо него пользователь видит запрос и сам решает, передавать ли сообщение вашему приложению. Приложение должно начать прослушивание до прихода SMS, а код затем извлекает из текста сообщения самостоятельно.
Что такое SMS-код с привязкой к домену на iOS?
Это SMS, последняя строка которого привязывает код к вашему домену: домен с префиксом @, пробел и код с префиксом #. Apple описывает этот формат для iOS 14 и новее. Автозаполнение предлагает код, только если сайт в Safari или связанный домен приложения совпадает с доменом в сообщении.
Как WebOTP читает SMS?
Страница вызывает navigator.credentials.get с параметром otp и транспортом sms. Когда приходит сообщение, последняя строка которого имеет вид @хост #код, а хост совпадает с источником страницы, браузер просит пользователя подтвердить и возвращает код. Нужен HTTPS; документирован Chrome на Android.
Почему мой OTP не подставляется автоматически?
Обычные причины: код нельзя однозначно определить, неверный или отсутствующий хеш приложения на Android, последняя строка не соответствует формату @домен #код, домен не совпадает со страницей или текст превысил лимит в байтах. Проверьте каждый пункт по правилам формата и протестируйте на реальном телефоне.
Поддерживает ли WhatsApp автоподстановку OTP?
Да. Шаблоны аутентификации Meta поддерживают кнопку копирования кода, кнопку автозаполнения one-tap и вариант zero-tap. Для one-tap и zero-tap нужны имя пакета Android-приложения и хеш подписи. Zero-tap работает только на Android, на других платформах пользователь получает кнопку копирования кода.
Источники
- SMS Retriever API: perform SMS verification — Google for Developers
- SMS User Consent API: request a one-time code — Google for Developers
- Enabling AutoFill for domain-bound SMS codes — Apple Developer
- Verify phone numbers on the web with the WebOTP API — Chrome for Developers
- WebOTP API — WICG specification
- Authentication templates — WhatsApp Business Platform, Meta for Developers
Читайте дальше
Ещё руководстваИнтеграции
Формат номера E.164: как преобразовать и проверить номер
Формат номера телефона E.164: правила, таблица примеров преобразования, требования API WhatsApp и SMS, регулярное выражение и проверка через libphonenumber.
9 мин чтения
Интеграции
Отправка SMS через API: примеры на Python, Node.js, PHP и cURL
Отправка SMS через API на Python, Node.js, PHP и cURL: одиночные и массовые отправки, Unicode и арабский, подсчёт сегментов, вебхуки статусов доставки и ошибки.
10 мин чтения
WhatsApp
OTP в WhatsApp или по SMS: стоимость, доставка и резервный канал
OTP в WhatsApp и OTP по SMS: модель стоимости, охват и доставка, удобство для пользователя, шаблоны аутентификации, резерв по SMS и защита от фрода.
10 мин чтения
