HTML: h1: Автозаполнение одноразового кода: autocomplete="one-time-code"

Атрибут autocomplete="one-time-code" сообщает браузеру и операционной системе, что поле предназначено для одноразового кода подтверждения (OTP). На совместимых устройствах пользователь может получить код из SMS и вставить его одним нажатием вместо ручного ввода.

Это простой progressive enhancement: если браузер не умеет автоматически подставлять OTP, поле продолжит работать как обычный <input>.

Не подходит для постоянного PIN-кода, пароля, CAPTCHA, recovery-кода или других значений, которые не являются одноразовым кодом подтверждения.

Готовое решение

<form action="/verify-code/" method="post">
	<label for="OtpCode">Код подтверждения</label>
	<input type="text" 
		id="OtpCode" 
		name="OtpCode" 
		inputmode="numeric" 
		autocomplete="one-time-code" 
		pattern="[0-9]{6}" 
		maxlength="6" 
		required 
	>
	<button type="submit">Подтвердить</button>
</form>

Здесь каждый атрибут выполняет свою задачу:

  • type="text" — OTP является строкой, а не числом. Код может начинаться с нуля;
  • inputmode="numeric" — показывает цифровую клавиатуру на мобильном устройстве;
  • autocomplete="one-time-code" — сообщает браузеру назначение поля;
  • pattern="[0-9]{6}" — разрешает шестизначный цифровой код;
  • maxlength="6" — ограничивает длину ввода;
  • required — запрещает отправку пустого значения средствами браузера.

Почему не type="number"?

Для OTP лучше использовать type="text". Одноразовый код — это последовательность символов, а не число, над которым выполняются математические операции.

Например, код:

012345

должен сохранить начальный ноль. Дополнительно type="number" может показывать элементы изменения числового значения, которые здесь не нужны.


Формат SMS

Для более надёжного распознавания кода можно использовать origin-bound формат SMS, в котором код связывается с доменом сайта.

Код подтверждения: 123456 @example.com #123456

Последняя строка содержит домен после @ и одноразовый код после #.

Для сайта example.com:

@example.com #123456

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


Пример использования

  1. Пользователь вводит номер телефона.
  2. Сервер генерирует одноразовый код, например 483921.
  3. Пользователь получает SMS.
  4. Браузер или операционная система распознаёт код.
  5. Над клавиатурой появляется предложение вставить 483921.
  6. Пользователь подтверждает форму.
  7. Сервер проверяет код и помечает его использованным.

Никакой JavaScript для самого autocomplete="one-time-code" не требуется.


Краевые случаи — сломается или будет работать хуже, если…

  • OTP разбит на шесть отдельных <input> — автоматическое заполнение обычно надёжнее работает с одним полем;
  • код содержит буквы, но установлен inputmode="numeric" и цифровой pattern;
  • браузер или операционная система не поддерживает получение OTP — пользователь просто введёт код вручную;
  • сообщение пришло на другое устройство, между которым и текущим устройством нет поддержки передачи кодов;
  • SMS имеет нестандартный формат, который система не смогла распознать;
  • JavaScript очищает или перерисовывает поле после того, как браузер вставил значение.

Если дизайн требует визуально показать шесть отдельных ячеек, практичнее оставить внутри один настоящий <input>, а разделение на символы сделать средствами CSS.


Безопасность

autocomplete="one-time-code" улучшает UX, но никак не проверяет код и не делает механизм OTP безопасным сам по себе.

Проверка всегда должна выполняться на сервере.

  • генерируйте код криптографически безопасным генератором;
  • задавайте ограниченный срок действия;
  • разрешайте использовать код только один раз;
  • привязывайте код к пользователю, сессии или конкретному действию;
  • ограничивайте количество попыток проверки;
  • ограничивайте частоту повторной отправки кодов;
  • не записывайте действующий OTP в обычные access/error/application logs;
  • после успешной проверки сразу делайте код недействительным.

Для критичных операций SMS-код не стоит рассматривать как единственный сильный фактор аутентификации: существуют SIM-swap, перехват сообщений и фишинг. Для более сильной защиты стоит рассмотреть WebAuthn/passkeys.


Дополнение: WebOTP API

autocomplete="one-time-code" и WebOTP — не одно и то же.

Первый вариант лишь сообщает браузеру назначение поля. WebOTP API позволяет поддерживаемому браузеру программно получить OTP из специально сформированного SMS.

Это можно добавить как progressive enhancement:

const OtpInput = document.querySelector('input[autocomplete="one-time-code"]');
if (OtpInput && 'OTPCredential' in window) {
	const Form = OtpInput.closest('form');
	const Abort = new AbortController();
	if (Form) {
		Form.addEventListener('submit', () =>
		 {
			Abort.abort();
		}
		, {
			once: true
		}
		);
	}
	navigator.credentials.get( {
		otp: {
			transport: ['sms']
		}
		, signal: Abort.signal
	}
	) .then((Credential) =>
	 {
		OtpInput.value = Credential.code;
		OtpInput.dispatchEvent(new Event('input', {
			bubbles: true
		}
		));
	}
	) .catch((Error) =>
	 {
		if (Error.name !== 'AbortError') {
			console.warn('WebOTP недоступен:', Error);
		}
	}
	);
}

WebOTP следует считать дополнительным улучшением. Основная форма должна нормально работать и без него.


Производительность

Сам атрибут autocomplete="one-time-code" практически ничего не стоит с точки зрения производительности: это обычная подсказка браузеру.

В реальном OTP-процессе основная задержка обычно находится не во фронтенде, а в генерации и доставке сообщения через SMS-провайдера.


Совместимость

Значение one-time-code поддерживается современными браузерами, но конкретное поведение автозаполнения зависит от браузера, операционной системы и источника OTP.

Поэтому код следует строить по принципу progressive enhancement:

<input type="text" inputmode="numeric" autocomplete="one-time-code" name="OtpCode" required >

Если автозаполнение доступно — пользователь получает более удобный интерфейс. Если нет — вводит код вручную.

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

Просмотров: 65
Материал помог? Оценка помогает находить устаревшие и спорные решения.

Комментарии

0

Нашли ошибку или хотите дополнить материал?

Комментариев пока нет.Можно первым дополнить материал или сообщить об ошибке.
Telegram