Изображение женщины, использующей OTP для входа в веб-приложение.

Подтверждайте номера телефонов в Интернете с помощью API WebOTP

Упростите для пользователей процедуру подтверждения телефона с помощью одноразовых паролей, полученных через СМС

Published on Updated on

Translated to: English, Español, Português, 한국어, 中文

Важный

Если вы хотите узнать больше о передовых методах использования форм SMS OTP, включая API WebOTP, прочитайте статью «Передовые методы использования форм SMS OTP».

Что такое API WebOTP?

В наши дни большинство людей в мире владеют мобильными устройствами, и разработчики обычно используют телефонные номера для идентификации пользователей услуг.

Существует множество способов проверки телефонных номеров, но один из наиболее распространенных — случайный одноразовый пароль (OTP), отправленный по СМС. Отправка этого кода обратно на сервер разработчика подтверждает, что данный номер телефона контролируется пользователем.

Эта идея уже используется во многих сценариях:

  • Номер телефона как идентификатор пользователя. При подписке на новую услугу некоторые веб-сайты запрашивают номер телефона вместо адреса электронной почты и используют его в качестве идентификатора учетной записи.
  • Двухфакторная проверка. При входе в систему веб-сайт запрашивает одноразовый код, отправленный по СМС, в дополнение к паролю или другому фактору проверки в качестве дополнительной меры безопасности.
  • Подтверждение об оплате. Запрос одноразового кода, отправленного по СМС при совершении платежа, помогает проверить намерение пользователя.

Текущий процесс неудобен пользователям, ведь нужно найти OTP в СМС-сообщениях, затем скопировать его и вставить в форму. Неудобство снижает конверсию на критически важных этапах пути потребителя. Многие крупнейшие мировые разработчики давно просили облегчить эту задачу. Для Android уже существует соответствующий API, как и для iOS и Safari.

API WebOTP позволяет приложению получать специальным образом форматированные сообщения, привязанные к домену приложения. Это делает возможным программное получение OTP из СМС и упрощает проверку номера телефона пользователя.

Warning

Злоумышленники могут подделать СМС и перехватить номер телефона человека. Операторы также могут передавать телефонные номера новым пользователям после блокировки сим-карты. Хотя SMS OTP полезен для проверки номера телефона в описанных выше случаях, мы рекомендуем использовать дополнительные и более надежные формы аутентификации (например, многофакторную аутентификацию и Web Authentication API) для создания новых сессий для этих пользователей.

Практический пример

Допустим, пользователь хочет подтвердить свой номер телефона на веб-сайте. Веб-сайт отправляет пользователю СМС-сообщение, и пользователь вводит OTP из сообщения, чтобы подтвердить принадлежность номера телефона.

С помощью API WebOTP эти действия выполняются легко, одним нажатием кнопки, как показано в видеоролике. Когда приходит текстовое сообщение, внизу появляется всплывающее окно, предлагающее пользователю подтвердить свой номер телефона. После нажатия кнопки Verify (Подтвердить) в нижнем окне браузер вставляет OTP в форму и происходит отправка, пользователю даже не нужно нажимать Continue (Продолжить).
endAside %}

Весь процесс показан на изображении ниже.

Схема API WebOTP

Запустите демонстрационный пример. Он не запрашивает номер телефона и не отправляет СМС на ваше устройство, но вы можете отправить СМС с другого устройства, скопировав текст, отображаемый в демонстрации. Это работает, потому что при использовании API WebOTP не имеет значения, кто отправитель.

  1. Перейдите на https://web-otp.glitch.me в Chrome 84 или более поздней версии на устройстве Android.
  2. Отправьте на свой телефон следующее СМС-сообщение с другого телефона.
Your OTP is: 123456.

@web-otp.glitch.me #12345

Получили ли вы СМС-сообщение и увидели ли подсказку о необходимости ввести код в поле ввода? Именно так работает API WebOTP для пользователей.

Важный

Если диалоговое окно не появилось, ознакомьтесь с разделом «Часто задаваемые вопросы».

Использование WebOTP API состоит из трех частей:

  • правильно аннотированный тег <input>;
  • JavaScript в вашем веб-приложении;
  • форматированный текст СМС-сообщения.

Начнем с тега <input>.

Аннотируйте тег <input>

Сам WebOTP работает без какой-либо HTML-аннотации, но для кросс-браузерной совместимости я настоятельно рекомендую добавить autocomplete="one-time-code" в тег <input>, в который пользователь должен ввести OTP.

Это дает возможность Safari 14 или более поздней версии браузера предлагать пользователю автоматически вставить OTP в поле <input> при получении СМС в формате, описанном в разделе «Отформатируйте СМС-сообщение», даже если браузер не поддерживает WebOTP.

HTML

<form>
<input autocomplete="one-time-code" required/>
<input type="submit">
</form>

Используйте API WebOTP

WebOTP несложный, поэтому просто скопируйте и вставьте следующий код. Далее я подробно объясню работу кода.

JavaScript

if ('OTPCredential' in window) {
window.addEventListener('DOMContentLoaded', e => {
const input = document.querySelector('input[autocomplete="one-time-code"]');
if (!input) return;
const ac = new AbortController();
const form = input.closest('form');
if (form) {
form.addEventListener('submit', e => {
ac.abort();
});
}
navigator.credentials.get({
otp: { transport:['sms'] },
signal: ac.signal
}).then(otp => {
input.value = otp.code;
if (form) form.submit();
}).catch(err => {
console.log(err);
});
});
}

Обнаружение функции

Обнаружение функции происходит так же, как и для многих других API. Прослушиватель события DOMContentLoaded будет ждать, когда дерево DOM будет готово к запросу.

JavaScript

if ('OTPCredential' in window) {
window.addEventListener('DOMContentLoaded', e => {
const input = document.querySelector('input[autocomplete="one-time-code"]');
if (!input) return;

const form = input.closest('form');

});
}
Caution

Для работы API WebOTP требуется безопасный источник (HTTPS). Обнаружение функции на веб-сайте с протоколом HTTP завершится ошибкой.

Обработайте OTP

Сам API WebOTP достаточно прост. Используйте navigator.credentials.get() для получения OTP. WebOTP добавляет к этому методу новый параметр otp. У него есть только одно свойство: transport, значением которого должен быть массив со строкой 'sms'.

JavaScript


navigator.credentials.get({
otp: { transport:['sms'] }

}).then(otp => {

Это запускает поток разрешений браузера при получении СМС-сообщения. Если разрешение предоставлено, возвращаемое обещание разрешается с помощью объекта OTPCredential.

Содержание полученного объекта `OTPCredential`

{
code: "123456" // Obtained OTP
type: "otp" // `type` is always "otp"
}

Затем передайте значение OTP в поле <input>. Отправка формы напрямую устранит шаг, требующий от пользователя нажатия кнопки.

JavaScript


navigator.credentials.get({
otp: { transport:['sms'] }

}).then(otp => {
input.value = otp.code;
if (form) form.submit();
}).catch(err => {
console.error(err);
});

Прерывание сообщения

В случае если пользователь вручную вводит OTP и отправляет форму, вы можете отменить вызов get(), используя экземпляр AbortController в объекте options.

JavaScript


const ac = new AbortController();

if (form) {
form.addEventListener('submit', e => {
ac.abort();
});
}

navigator.credentials.get({
otp: { transport:['sms'] },
signal: ac.signal
}).then(otp => {

Отформатируйте СМС-сообщение

Сам API выглядит простым, но есть несколько моментов, которые необходимо знать перед его использованием. Сообщение должно быть отправлено после вызова navigator.credentials.get() и должно быть получено на устройстве, на котором была вызвана функция get(). Наконец, сообщение должно соответствовать следующему формату:

  • сообщение начинается с удобочитаемого текста (необязательно), который содержит буквенно-цифровую строку из 4–10 символов с как минимум одной цифрой, а в последней строке указываются URL-адрес и одноразовый пароль (OTP);
  • символ @ должен предшествовать доменной части URL-адреса веб-сайта, вызвавшего API;
  • URL-адрес должен содержать знак решетки (' # '), за которым следует OTP.

Например:

Your OTP is: 123456.

@www.example.com #123456

Вот плохие примеры:

Пример неправильно оформленного СМСПочему это не сработает
Here is your code for @example.com #123456@ должен быть первым символом последней строки.
Your code for @example.com is #123456@ должен быть первым символом последней строки.
Your verification code is 123456

@example.com\t#123456
Между @host и #code должен стоять одинарный пробел.
Your verification code is 123456

@example.com #123456
Между @host и #code должен стоять одинарный пробел.
Your verification code is 123456

@ftp://example.com #123456
Схема URL не должна включаться в сообщение.
Your verification code is 123456

@https://example.com #123456
Схема URL не должна включаться в сообщение.
Your verification code is 123456

@example.com:8080 #123456
Порт не должен включаться в сообщение.
Your verification code is 123456

@example.com/foobar #123456
Путь не должен включаться в сообщение.
Your verification code is 123456

@example .com #123456
В доменном имени не должно быть пробелов.
Your verification code is 123456

@domain-forbiden-chars-#%/:<>?@[] #123456
В доменном имени не должно быть запрещенных символов.
@example.com #123456

Mambo Jumbo
@host и #code должны быть в последней строке.
@example.com #123456

App hash #oudf08lkjsdf834
@host и #code должны быть в последней строке.
Your verification code is 123456

@example.com 123456
Отсутствует # .
Your verification code is 123456

example.com #123456
Отсутствует @ .
Hi mom, did you receive my last textОтсутствуют @ и # .

Демонстрации

Попробуйте различные сообщения с демонстрацией: https://web-otp.glitch.me

Вы также можете «форкнуть» пример и создать свою версию: https://glitch.com/edit/#!/web-otp.

Используйте WebOTP из iframe с перекрестным происхождением

Ввод SMS OTP в iframe с перекрестным происхождением обычно используется для подтверждения платежа, особенно с использованием протокола 3D Secure. API WebOTP предоставляет OTP с привязкой к вложенным источникам, используя стандартный формат для поддержки iframes с перекрестным происхождением. Например:

  • Пользователь заходит на сайт shop.example, чтобы купить пару обуви с помощью кредитной карты.
  • После ввода номера кредитной карты интегрированный поставщик платежей показывает форму из bank.example в окне iframe, предлагающую пользователю подтвердить свой номер телефона для быстрой оплаты.
  • bank.example отправляет СМС с OTP пользователю, чтобы он мог ввести OTP для подтверждения своей личности.

Чтобы использовать API WebOTP из iframe с перекрестным происхождением, нужно предпринять следующие два действия:

  • аннотировать в СМС-сообщении источник iframe верхнего уровня и источник iframe;
  • настроить политику разрешений, чтобы разрешить iframe с перекрестным происхождением напрямую получать OTP от пользователя.
API WebOTP в iframe в действии.

Попробуйте демонстрацию на https://web-otp-iframe-demo.stackblitz.io.

Аннотируйте связанные источники (bound-origins) в текстовом СМС-сообщении

Когда WebOTP API вызывается из iframe, СМС-сообщение в последней строке должно содержать источник iframe верхнего уровня (начинается с символа @), затем OTP (начинается с символа #) и источник iframe (начинается с символа @).

Your verification code is 123456

@shop.example #123456 @bank.exmple

Настройте политику разрешений

Чтобы использовать WebOTP в iframe с перекрестным происхождением, эмбеддер должен предоставить доступ к этому API через политику разрешений otp-credentials, чтобы избежать непреднамеренного поведения. В общем, есть два способа достичь этой цели:

через заголовок HTTP:

Permissions-Policy: otp-credentials=(self "https://bank.example")

через атрибут `allow` тега iframe:

<iframe src="https://bank.example/…" allow="otp-credentials"></iframe>

См. другие примеры того, как указать политику разрешений.

На данный момент Chrome поддерживает вызовы API WebOTP только из iframe с перекрестным происхождением, которые имеют не более одного уникального источника в цепочке предков. В следующих сценариях:

  • a.com -> b.com
  • a.com -> b.com -> b.com
  • a.com -> a.com -> b.com
  • a.com -> b.com -> c.com

использование WebOTP на b.com поддерживается, а на c.com — нет.

Обратите внимание, что следующий сценарий также не поддерживается из-за отсутствия спроса и сложностей UX.

  • a.com -> b.com -> a.com (вызывает API WebOTP)

Часто задаваемые вопросы

Диалог не появляется, хотя я отправляю правильно отформатированное сообщение. Что не так?

При тестировании API учтите следующие моменты:

  • Если номер телефона отправителя включен в список контактов получателя, этот API не будет запускаться из-за конструкции базового API SMS User Consent.
  • Если вы используете рабочий профиль на своем устройстве Android и WebOTP не работает, попробуйте вместо этого установить и использовать Chrome в своем личном профиле (т. е. в том же профиле, в котором вы получаете СМС).

Вернитесь к разделу о формате, чтобы проверить, правильно ли отформатировано ваше СМС.

Обладает ли этот API кросс-браузерной совместимостью?

Chromium и WebKit согласовали формат текстовых СМС-сообщений, и Apple объявила о его поддержке в Safari, начиная с iOS 14 и macOS Big Sur. Хотя Safari не поддерживает API WebOTP JavaScript, аннотируя input с помощью autocomplete=["one-time-code"], клавиатура по умолчанию автоматически предлагает ввести OTP, если СМС-сообщение соответствует формату.

Насколько безопасно использовать СМС для аутентификации?

Хотя SMS OTP полезен для проверки номера телефона при его первом предоставлении, следует с осторожностью использовать проверку номера телефона через СМС для повторной аутентификации, поскольку телефонные номера могут быть перехвачены и повторно использованы операторами связи. WebOTP — удобный механизм повторной аутентификации и восстановления доступа, но службы должны сочетать его с дополнительными факторами, такими как аутентификация на основе знаний (KBA), или использовать API Web Authentication для надежной аутентификации.

Куда сообщать об ошибках в реализации Chrome?

Вы нашли ошибку в реализации Chrome?

  • Сообщите об ошибке на https://new.crbug.com. Укажите как можно больше подробностей, простые инструкции по воспроизведению и установите Components в значение Blink>WebOTP.

Чем я могу помочь с этой функцией?

Планируете ли вы использовать API WebOTP? Ваша публичная поддержка поможет нам определить приоритетность функций и покажет другим производителям браузеров, насколько важно реализовать поддержку данных функций. Отправьте твит на @ChromiumDev с хештегом #WebOTP и сообщите нам, где и как вы его используете.

Updated on Improve article

We serve cookies on this site to analyze traffic, remember your preferences, and optimize your experience.