WooCommerce: как реализовать авторизацию через SMS без плагинов

Диагностика задачи: зачем нужна авторизация через SMS в WooCommerce

Стандартная регистрация и авторизация в WooCommerce основаны на пароле, что может отпугнуть часть пользователей из-за сложности запоминания или опасений по безопасности. Авторизация через одноразовые коды по SMS (OTP) повышает удобство и безопасность входа, особенно для мобильной аудитории.

Однако встроенных средств для реализации такой схемы в WooCommerce нет, и многие прибегают к плагинам. Но плагины могут создавать нагрузку и конфликты. В статье разберём, как реализовать авторизацию через SMS без плагинов, используя собственный код и сервис SMS-рассылки.

Требования и подготовка

  • WooCommerce установлен и работает на сайте.
  • Аккаунт и API у SMS-провайдера (например, sms.ru, Twilio, или любой другой.
  • Базовые знания PHP и работы с WordPress/WooCommerce хуками.

Как работает схема авторизации через SMS

  1. Пользователь вводит номер телефона вместо логина и пароля.
  2. На номер отправляется одноразовый код (OTP).
  3. Пользователь вводит код на сайте.
  4. Если код верный и актуальный, пользователь авторизуется или создаётся новый аккаунт.

Шаг 1. Добавляем поля для номера телефона и кода на страницу входа WooCommerce

Добавим в шаблон входа два поля: для телефона и для одноразового кода.

add_action('woocommerce_login_form', function() {
    echo '<p class="form-row form-row-wide">';
    echo '<label for="phone_number">Номер телефона (введите без +)</label>';
    echo '<input type="text" name="phone_number" id="phone_number" class="input-text" autocomplete="tel" />';
    echo '</p>';
    echo '<p class="form-row form-row-wide">';
    echo '<label for="sms_code">Код из SMS</label>';
    echo '<input type="text" name="sms_code" id="sms_code" class="input-text" autocomplete="one-time-code" />';
    echo '</p>';
    echo '<p class="form-row"><button type="button" id="send_sms_code" class="button">Отправить код</button></p>';
});

Шаг 2. Обработка отправки SMS кода через AJAX

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

add_action('wp_ajax_send_sms_code', 'send_sms_code_handler');
add_action('wp_ajax_nopriv_send_sms_code', 'send_sms_code_handler');

function send_sms_code_handler() {
    if ( empty($_POST['phone']) ) {
        wp_send_json_error('Номер телефона не указан');
    }

    $phone = preg_replace('/[^0-9]/', '', sanitize_text_field($_POST['phone']));
    if (strlen($phone) < 10) {
        wp_send_json_error('Неверный формат номера');
    }

    // Генерируем 6-значный код
    $code = wp_rand(100000, 999999);
    $expires = time() + 300; // код действителен 5 минут

    // Сохраняем код и время в сессии
    if ( !session_id() ) {
        session_start();
    }
    $_SESSION['sms_code_'.$phone] = ['code' => $code, 'expires' => $expires];

    // Отправляем SMS через API (пример для sms.ru)
    $api_id = 'ВАШ_API_ID';
    $message = "Ваш код для входа: $code";
    $url = "https://sms.ru/sms/send?api_id={$api_id}&to={$phone}&msg=" . rawurlencode($message) . "&json=1";

    $response = wp_remote_get($url);
    if (is_wp_error($response)) {
        wp_send_json_error('Ошибка отправки SMS');
    }
    $body = json_decode(wp_remote_retrieve_body($response), true);
    if ($body['status'] !== 'OK') {
        wp_send_json_error('Ошибка сервера SMS: ' . $body['status_text']);
    }

    wp_send_json_success('Код отправлен');
}

add_action('wp_enqueue_scripts', function() {
    if (is_account_page()) {
        wp_enqueue_script('sms-login', get_stylesheet_directory_uri() . '/sms-login.js', ['jquery'], null, true);
        wp_localize_script('sms-login', 'smsLogin', ['ajaxurl' => admin_url('admin-ajax.php')]);
    }
});

Шаг 3. Скрипт для отправки кода при клике

Создайте файл sms-login.js в вашей теме с таким содержимым:

jQuery(document).ready(function($){
    $('#send_sms_code').on('click', function(e){
        e.preventDefault();
        var phone = $('#phone_number').val();
        if(!phone) {
            alert('Введите номер телефона');
            return;
        }
        $.post(smsLogin.ajaxurl, {action: 'send_sms_code', phone: phone}, function(response){
            if(response.success) {
                alert('Код отправлен');
            } else {
                alert('Ошибка: ' + response.data);
            }
        });
    });
});

Шаг 4. Проверяем код и авторизуем пользователя

Добавим проверку кода при попытке логина. Если код валиден, авторизуем пользователя по номеру телефона или создаём его.

add_filter('authenticate', 'sms_code_authenticate', 30, 3);
function sms_code_authenticate($user, $username, $password) {
    if ( !empty($_POST['phone_number']) && !empty($_POST['sms_code']) ) {
        $phone = preg_replace('/[^0-9]/', '', sanitize_text_field($_POST['phone_number']));
        $code = sanitize_text_field($_POST['sms_code']);

        if ( !session_id() ) {
            session_start();
        }
        if ( empty($_SESSION['sms_code_'.$phone]) ) {
            return new WP_Error('invalid_code', 'Код не отправлялся на этот номер');
        }

        $data = $_SESSION['sms_code_'.$phone];
        if ( time() > $data['expires'] ) {
            unset($_SESSION['sms_code_'.$phone]);
            return new WP_Error('expired_code', 'Код истёк');
        }

        if ( $code !== $data['code'] ) {
            return new WP_Error('wrong_code', 'Неверный код');
        }

        unset($_SESSION['sms_code_'.$phone]);

        // Ищем пользователя по метаполю с номером телефона
        $user_query = new WP_User_Query(array(
            'meta_key' => 'phone_number',
            'meta_value' => $phone,
            'number' => 1
        ));

        if ( !empty($user_query->results) ) {
            return $user_query->results[0];
        } else {
            // Создаём пользователя без пароля
            $userdata = array(
                'user_login' => 'user_' . $phone,
                'user_pass' => wp_generate_password(12, false),
                'user_email' => '',
                'display_name' => $phone
            );
            $user_id = wp_insert_user($userdata);
            if (is_wp_error($user_id)) {
                return $user_id;
            }
            update_user_meta($user_id, 'phone_number', $phone);
            return get_user_by('id', $user_id);
        }
    }
    return $user;
}

Проверка результата

  • Зайдите на страницу входа WooCommerce.
  • Введите корректный номер телефона и нажмите "Отправить код".
  • Получите SMS с кодом (проверьте логи или реально получите на телефон).
  • Введите код и отправьте форму входа.
  • Если код верный, вы должны войти или зарегистрироваться без пароля.

Частые ошибки и их исправление

  • Код не отправляется: проверьте API ID, корректность запроса и ограничения SMS-провайдера.
  • Сессии нет или код не сохраняется: убедитесь, что session_start() вызывается корректно, без ошибок.
  • Пользователь не авторизуется: проверьте, что метаполе phone_number используется одинаково и что пользователь создаётся без ошибок.
  • Код просрочен слишком быстро: увеличьте время жизни кода в переменной $expires.

Практические советы по безопасности и производительности

  • Используйте HTTPS для защиты данных формы и запросов.
  • Ограничьте количество запросов на отправку SMS с одного IP или номера телефона, чтобы избежать спама.
  • Храните одноразовые коды в серверной сессии, не в базе данных, чтобы избежать избыточной нагрузки.
  • Обрабатывайте ошибки API SMS, чтобы не вводить пользователя в заблуждение.
  • Для больших проектов рассмотрите кеширование и более сложное управление сессиями.

Сравнение вариантов реализации авторизации через SMS

МетодПлюсыМинусыРесурсы
Плагины (например, OTP Login)Быстрая настройка, готовый функционалВес, возможные конфликты, ограниченная кастомизацияWordPress.org
Кастомный код + SMS APIПолный контроль, легковесность, гибкостьТребует знаний PHP, поддержка и доработка на разработчикеSMS API, документация WooCommerce
Внешние сервисы (Authy, Firebase)Высокая надёжность, расширенный функционалСложность интеграции, стоимостьAPI сервисов
Как использовать AJAX в WordPress для обновления контента без перезагрузки страницы
16.12.2025
Как удалить пустые метаполя в WordPress с помощью кода
01.04.2026
Как создать свой плагин для WordPress с настройками
19.11.2025
Как использовать WP хуки для автоматической отправки отчетов в WordPress
22.01.2026
Как использовать хуки для динамического формирования метаданных в WordPress
04.01.2026