Изображение женщины, использующей 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

This site uses cookies to deliver and enhance the quality of its services and to analyze traffic. If you agree, cookies are also used to serve advertising and to personalize the content and advertisements that you see. Learn more about our use of cookies.