DevGang
Авторизоваться

Улучшенная двухфакторная аутентификация с помощью WebOTP

Двухфакторная аутентификация (2FA) - отличный способ повысить безопасность учетных записей пользователей в приложении. Это помогает защитить от распространенных проблем с паролями, таких как выбор пользователями легко угадываемых паролей или повторное использование одного и того же пароля на нескольких сайтах. Существуют различные способы реализации двухфакторной аутентификации, включая SMS, с использованием приложения-аутентификатора и WebAuthn.

SMS является наиболее широко используемым и никуда не денется, поэтому мы, разработчики, должны сделать все возможное, чтобы создать лучший сервис SMS 2FA для наших пользователей. API WebOTP - это один из способов, которым мы можем помочь уменьшить трудности при входе в систему и даже обеспечить некоторую защиту от фишинга.

Что такое WebOTP API?

WebOTP API - это расширение к Credential Management API. Credential Management API начинался с предоставления нам возможности хранить учетные данные и получать к ним доступ в диспетчере паролей браузера, но теперь включает WebAuthn и двухфакторную аутентификацию. WebOTP API позволяет нам запрашивать у пользователя разрешение на считывание кода 2FA из входящего SMS-сообщения.

Когда вы внедряете WebOTP API, второй шаг процесса входа в систему может перейти от неудобного процесса чтения и копирования нескольких цифр из SMS-сообщения к нажатию одной кнопки. Большое улучшение, я думаю, вы согласитесь.

Чтобы внедрить Web OTP, вам нужно будет сделать две вещи:

  1. Обновите отправляемое сообщение в формате WebOTP
  2. Добавьте немного JavaScript на страницу входа, чтобы запросить разрешение на чтение сообщения

SMS-сообщение

Чтобы WebOTP API распознал сообщение как входящий код 2FA, вам нужно добавить строку в конец отправляемого вами сообщения. Эта строка должна содержать символ @, за которым следует домен сайта, на который будет входить ваш пользователь, затем пробел, символ # и затем сам код. Если ваш пользователь входит в систему на example.com и код, который вы им отправляете, равен 123456, тогда сообщение должно выглядеть следующим образом:

Ваш код для входа в приложение - 123456
@example.com #123456

Домен привязывает сообщение к веб-сайту, на который пользователь должен войти. Это помогает защитить от фишинга, WebOTP нельзя использовать для запроса кода из SMS, если домен, в который пользователь входит, не совпадает с доменом в сообщении. Очевидно, что это не может остановить пользователя, копирующего код напротив сообщения, но это может заставить их задуматься, если они ожидают такого поведения.

JavaScript

Как только вы настроите свои сообщения в нужном формате, вам понадобится некоторый JavaScript на вашей странице 2nd factor, который запустит WebOTP API, запросит у пользователя разрешение на доступ к сообщению и соберет код.

Самая минимальная версия этого кода выглядит следующим образом:

if ('OTPCredential' in window) {
  navigator.credentials.get({
    otp: {
      transport: ['sms']
    }
  }).then((otp) => {
    submitOTP(otp.code);
  });
}

Мы просим объект navigator.credentials получить одноразовый пароль (OTP) от передачи SMS. Если браузер обнаружит входящее сообщение с нужным доменом и кодом в нем, пользователю будет предложено запросить доступ. Если пользователь одобряет обещание, оно разрешается с помощью объекта otp, который имеет свойство code. Затем вы можете ввести этот код в форму и завершить процесс входа пользователя в систему.

Более полная версия кода, которая обрабатывает такие вещи, как поиск входных данных и формы, отмена запроса, если форма отправлена, и отправка формы, если запрос выполнен успешно, выглядит следующим образом:

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.error(err);
    });
  });
}

Это будет работать для многих сайтов, но копирование и вставка кода - не лучший способ поделиться кодом, поэтому придумаем что-то немного более простое.

Декларативный WebOTP с веб-компонентами

В Safari вы можете получить поведение, аналогичное поведению WebOTP API, добавив один атрибут к элементу <input> для кода OTP. Установка autocomplete="one-time-code" приведет к тому, что Safari предложит код из SMS через автозаполнение.

Вдохновленный этим, я хотел сделать WebOTP таким же простым. Итак, мы опубликовали веб-компонент, компонент <web-otp-input>, который обрабатывает весь процесс. Вы можете увидеть весь код и как его использовать на GitHub. Для краткого примера вы можете добавить компонент на свою страницу в качестве модуля ES:

<script type="module" src="https://unpkg.com/@philnash/web-otp-input"></script>

Или установите его в свой проект из npm:

npm install @philnash/web-otp-input

и импортируйте его в свое приложение:

import { WebOTPInput } from "@philnash/web-otp-input";

Затем вы можете обернуть <web-otp-input> вокруг вашего существующего <input> в <form>, например:

<form action="/verification" method="POST">
  <div>
    <label for="otp">Enter your code:</label>
    <web-otp-input>
      <input type="text" autocomplete="one-time-code" inputmode="numeric" id="otp" name="otp" />
    </web-otp-input>
  </div>
  <button type="submit">Submit</button>
</form>

Тогда работа с WebOTP будет происходить автоматически для любого пользователя в браузере, который его поддерживает, без написания какого-либо дополнительного JavaScript.

WebOTP: лучший опыт

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

Бывают даже случаи, когда это работает и для настольных браузеров. Для пользователя с Chrome на рабочем столе и Chrome на Android и вошедшего в свою учетную запись Google на обоих устройствах, вход на рабочем столе вызовет уведомление на мобильном устройстве с просьбой одобрить отправку кода на рабочий стол. Одобрив это на мобильных устройствах, вы передаете код в настольный браузер. Вам даже не нужно писать больше кода, чтобы справиться с этим, все, что вам нужно, - это JavaScript из этой статьи.

Если вы создаете двухфакторную аутентификацию или верификацию по телефону, рассмотрите возможность внедрения WebOTP API, чтобы упростить этот процесс для ваших пользователей.

#JavaScript #Security
Комментарии
Чтобы оставить комментарий, необходимо авторизоваться