WooCommerce: авторизация и регистрация без перезагрузки страниц

Проблема: зачем нужна AJAX авторизация и регистрация в WooCommerce

Стандартные формы авторизации и регистрации WooCommerce обновляют страницу при отправке данных, что ухудшает UX, особенно на мобильных устройствах. Пользователи вынуждены ждать перезагрузки, а при ошибках форма сбрасывается. Решение — реализовать AJAX-запросы для авторизации/регистрации без перезагрузки.

Диагностика проблемы

Проверьте, что стандартные формы WooCommerce отправляют данные через POST и после отправки происходит перезагрузка страницы. Откройте консоль браузера (F12) и убедитесь, что при нажатии кнопки входа/регистрации происходит запрос с перезагрузкой, а не AJAX-запрос.

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

Как реализовать AJAX авторизацию и регистрацию в WooCommerce: пошаговое решение

1. Подключение скриптов и локализация AJAX URL

Добавьте в functions.php вашей темы или дочерней темы следующий код, чтобы подключить JS и передать адрес AJAX:

add_action('wp_enqueue_scripts', 'wpfind_enqueue_ajax_scripts');
function wpfind_enqueue_ajax_scripts() {
    if (is_account_page()) { // только на странице аккаунта
        wp_enqueue_script('wpfind-ajax-auth', get_stylesheet_directory_uri() . '/js/ajax-auth.js', ['jquery'], '1.0', true);
        wp_localize_script('wpfind-ajax-auth', 'wpfind_ajax_object', [
            'ajax_url' => admin_url('admin-ajax.php'),
            'nonce' => wp_create_nonce('wpfind-ajax-auth-nonce')
        ]);
    }
}

2. Создание JS для перехвата формы и отправки AJAX

В файле js/ajax-auth.js напишите следующий код, который будет отправлять данные формы регистрации и авторизации без перезагрузки:

jQuery(document).ready(function($) {
    // Перехват формы входа
    $('#customer_login').on('submit', function(e) {
        e.preventDefault();
        var form = $(this);
        var data = {
            action: 'wpfind_ajax_login',
            username: form.find('#username').val(),
            password: form.find('#password').val(),
            security: wpfind_ajax_object.nonce
        };
        $.post(wpfind_ajax_object.ajax_url, data, function(response) {
            if(response.success) {
                location.reload(); // обновляем страницу после успеха
            } else {
                form.find('.woocommerce-error').remove();
                form.prepend('<ul class="woocommerce-error"><li>' + response.data + '</li></ul>');
            }
        });
    });

    // Перехват формы регистрации
    $('#customer_registration').on('submit', function(e) {
        e.preventDefault();
        var form = $(this);
        var data = {
            action: 'wpfind_ajax_register',
            email: form.find('#reg_email').val(),
            password: form.find('#reg_password').val(),
            security: wpfind_ajax_object.nonce
        };
        $.post(wpfind_ajax_object.ajax_url, data, function(response) {
            if(response.success) {
                location.reload();
            } else {
                form.find('.woocommerce-error').remove();
                form.prepend('<ul class="woocommerce-error"><li>' + response.data + '</li></ul>');
            }
        });
    });
});

3. Обработка AJAX запросов в PHP

Добавьте в functions.php следующий код для обработки запросов авторизации и регистрации:

add_action('wp_ajax_nopriv_wpfind_ajax_login', 'wpfind_ajax_login_handler');
add_action('wp_ajax_nopriv_wpfind_ajax_register', 'wpfind_ajax_register_handler');

function wpfind_ajax_login_handler() {
    check_ajax_referer('wpfind-ajax-auth-nonce', 'security');

    $username = isset($_POST['username']) ? sanitize_user($_POST['username']) : '';
    $password = isset($_POST['password']) ? $_POST['password'] : '';

    $creds = [
        'user_login'    => $username,
        'user_password' => $password,
        'remember'      => true
    ];

    $user = wp_signon($creds, false);

    if (is_wp_error($user)) {
        wp_send_json_error($user->get_error_message());
    } else {
        wp_send_json_success();
    }
}

function wpfind_ajax_register_handler() {
    check_ajax_referer('wpfind-ajax-auth-nonce', 'security');

    $email = isset($_POST['email']) ? sanitize_email($_POST['email']) : '';
    $password = isset($_POST['password']) ? $_POST['password'] : '';

    if (empty($email) || empty($password)) {
        wp_send_json_error('Email и пароль обязательны.');
    }
    if (!is_email($email)) {
        wp_send_json_error('Некорректный email.');
    }
    if (email_exists($email)) {
        wp_send_json_error('Пользователь с таким email уже существует.');
    }

    $username = sanitize_user(current(explode('@', $email)));
    $user_id = wp_create_user($username, $password, $email);

    if (is_wp_error($user_id)) {
        wp_send_json_error($user_id->get_error_message());
    }

    wp_set_current_user($user_id);
    wp_set_auth_cookie($user_id);

    wp_send_json_success();
}

Проверка результата после внедрения

  • Откройте страницу входа или регистрации WooCommerce.
  • Попробуйте войти с некорректными данными — ошибки должны выводиться без перезагрузки.
  • При успешном входе или регистрации страница автоматически обновится, и пользователь будет авторизован.
  • Проверьте консоль браузера — не должно быть ошибок JavaScript и сетевых ошибок AJAX.

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

  • Ошибка 400 или 403 при вызове admin-ajax.php — проверьте nonce и правильность передачи параметров в AJAX-запросе.
  • Форма не перехватывается JS — убедитесь в правильности селекторов #customer_login и #customer_registration, они должны совпадать с классами/ID вашей темы.
  • Пользователь не авторизуется после регистрации — проверьте, вызываются ли функции wp_set_auth_cookie и wp_set_current_user.
  • Конфликты с кэшированием — исключите страницу аккаунта из кэширования, иначе AJAX может возвращать старые данные.

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

  • Всегда проверяйте nonce в AJAX обработчиках для защиты от CSRF.
  • Ограничьте количество попыток входа через AJAX, чтобы избежать перебора паролей (можно использовать плагин Limit Login Attempts).
  • Минимизируйте JS скрипты и подключайте только на нужных страницах.
  • Используйте HTTPS для безопасной передачи данных.

Сравнение подходов: плагин vs кастомный код

МетодПреимуществаНедостатки
Готовый плагин AJAX авторизацииБыстрое внедрение, поддержка, часто есть дополнительные функцииМожет быть избыточным, нагрузка, несовместимости
Кастомный код с AJAXЛегкий, гибкий, контролируемый, без лишних функцийТребует знаний PHP и JS, нужно поддерживать самостоятельно

Сайт в разработке, скоро здесь будет портал о WordPress.