WordPress авторизация по OTP без SMS: настройка и примеры кода

Что такое OTP и почему стоит отказаться от SMS

Одноразовые пароли (OTP) — это временные коды, которые используются для подтверждения личности пользователя при входе в систему. Традиционно OTP отправляются через SMS, но этот метод имеет ряд недостатков: задержки доставки, возможные проблемы с безопасностью из-за перехвата сообщений, а также дополнительные расходы на отправку SMS.

Вместо этого можно использовать альтернативные способы генерации и передачи OTP, например, через email, push-уведомления, приложения-генераторы токенов (Google Authenticator, Authy) или даже через специальные плагины WordPress.

В этой статье мы рассмотрим, как реализовать авторизацию по OTP без использования SMS, используя email и генерацию кода на сервере, с примерами кода и рекомендациями по безопасности.

Настройка WordPress для авторизации по OTP через email

Генерация и сохранение OTP

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

  • Код должен быть случайным и достаточно длинным (например, 6 цифр).
  • Срок действия кода — например, 5 минут.
  • Код хранится в базе, чтобы можно было проверить его при входе.
function wpauth_generate_otp_for_user($user_id) {
    $otp = wp_rand(100000, 999999); // 6-значный код
    $expire = time() + 300; // 5 минут
    update_user_meta($user_id, 'wpauth_otp_code', $otp);
    update_user_meta($user_id, 'wpauth_otp_expire', $expire);
    return $otp;
}

Отправка OTP по email

После генерации кода отправим его пользователю на email. Для этого используем стандартную функцию wp_mail:

function wpauth_send_otp_email($user_email, $otp) {
    $subject = 'Ваш одноразовый код для входа на сайт';
    $message = "Здравствуйте!\nВаш код для входа: {$otp}\nОн действителен 5 минут.";
    wp_mail($user_email, $subject, $message);
}

Добавление формы ввода OTP на страницу входа

Для реализации процесса авторизации создадим двухэтапную форму:

  1. Пользователь вводит логин и нажимает "Получить код".
  2. Если логин корректен, генерируется OTP и отправляется на email.
  3. Пользователь вводит полученный код и подтверждает вход.

Реализуем обработчики и форму с помощью хуков login_form и authenticate. Пример упрощённой формы:

add_action('login_form', 'wpauth_add_otp_field');
function wpauth_add_otp_field() {
    if (isset($_POST['log']) && isset($_POST['wpauth_otp_step'])) {
        echo '<p><label>Введите код из email</label><br><input type="text" name="wpauth_otp_code" size="20" /></p>';
    } else {
        echo '<p><input type="hidden" name="wpauth_otp_step" value="1" /></p>';
    }
}

Далее в функции аутентификации проверим введённый код:

add_filter('authenticate', 'wpauth_authenticate_with_otp', 30, 3);
function wpauth_authenticate_with_otp($user, $username, $password) {
    if (isset($_POST['wpauth_otp_step']) && $_POST['wpauth_otp_step'] == '1') {
        // Первый шаг: проверяем логин, генерируем и отправляем OTP
        $user = get_user_by('login', $username);
        if (!$user) {
            return new WP_Error('invalid_login', 'Неверный логин');
        }
        $otp = wpauth_generate_otp_for_user($user->ID);
        wpauth_send_otp_email($user->user_email, $otp);
        // Останавливаем обычный вход, показываем форму ввода OTP
        return null;
    } elseif (isset($_POST['wpauth_otp_code'])) {
        // Второй шаг: проверяем OTP
        $user = get_user_by('login', $username);
        if (!$user) {
            return new WP_Error('invalid_login', 'Неверный логин');
        }
        $saved_otp = get_user_meta($user->ID, 'wpauth_otp_code', true);
        $expire = get_user_meta($user->ID, 'wpauth_otp_expire', true);
        if (time() > $expire) {
            return new WP_Error('otp_expired', 'Код истёк');
        }
        if ($_POST['wpauth_otp_code'] != $saved_otp) {
            return new WP_Error('invalid_otp', 'Неверный код');
        }
        // Успешная авторизация
        delete_user_meta($user->ID, 'wpauth_otp_code');
        delete_user_meta($user->ID, 'wpauth_otp_expire');
        return $user;
    }
    return $user;
}

Рекомендации по безопасности и UX

Важно учитывать, что при использовании OTP без пароля нужно максимально защитить процесс от злоупотреблений:

  • Ограничьте количество попыток ввода OTP, чтобы избежать перебора.
  • Используйте nonce и проверяйте их в формах для защиты от CSRF.
  • Логируйте успешные и неуспешные попытки для анализа.
  • Добавьте таймаут между запросами OTP.

Для улучшения пользовательского опыта можно интегрировать уведомления через плагины, например, использовать WPRemark для показа сообщений об ошибках и успехе.

Использование готовых плагинов для OTP без SMS

Если не хочется писать код самому, можно обратить внимание на готовые решения. Некоторые популярные плагины поддерживают OTP через email или приложения-генераторы токенов:

  • WP Simple OTP Verification — бесплатный плагин с поддержкой email для OTP.
  • WP 2FA — расширенный плагин с множеством способов двухфакторной аутентификации, включая OTP через приложения.

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

WordPress авторизация через SMS и Email с использованием WPQRCode
19.02.2026
WordPress регистрация без подтверждения по Email: как реализовать и зачем
03.02.2026
WordPress авторизация без пароля: как настроить и использовать
31.10.2025
WordPress удаление пользователя при удалённом запросе: практическое руководство
06.12.2025
WordPress кастомные сообщения об ошибках при входе: настройка и примеры
01.12.2025