Lapsha Suspended Registration
Плагин для WordPress для расширенных настроек регистрации
by Lapsha Dev · github.com/qstanay/lapsha-suspended-registration
Install
No release zip yet. The repository archive installs, but the folder name will carry the branch suffix and updates will not flow:
wp plugin install https://github.com/qstanay/lapsha-suspended-registration/archive/refs/heads/main.zipПлагин для WordPress/WooCommerce, заменяющий стандартную регистрацию на управляемый процесс с подтверждением email, встроенной капчей и защитой от спама.
Описание
Lapsha Suspended Registration перехватывает AJAX-регистрацию WooCommerce (обработчик ajaxreg) и вместо немедленного создания пользователя сохраняет заявку в отдельную таблицу базы данных. Новому пользователю отправляется письмо со ссылкой подтверждения. Реальный аккаунт WordPress создается только после перехода по ссылке. Неподтвержденные заявки автоматически удаляются по расписанию cron.
Если подтверждение email отключено в настройках, плагин создает пользователя немедленно через wc_create_new_customer, сохраняя при этом все прочие механизмы защиты (капча, honeypot, ограничение по IP).
Системные требования
- WordPress 5.8 или выше
- PHP 7.4 или выше
- WooCommerce (для полной функциональности регистрации через
wc_create_new_customer)
Установка
- Скопировать папку
lapsha-suspended-registrationв директориюwp-content/plugins/. - Активировать плагин на странице "Плагины" в админке WordPress.
- При активации автоматически создаются две таблицы в базе данных и регистрируется cron-задача.
- Перейти в "Настройки" -> "Lapsha Reg" для конфигурации.
Настройки
Страница настроек доступна только администраторам: Настройки -> Lapsha Reg.
Основные настройки
| Параметр | Тип | По умолчанию | Описание |
|---|---|---|---|
| Плагин активен | Чекбокс | Вкл | Глобальный переключатель. При выключении все хуки регистрации, капчи и rate limiter не подключаются. |
| Подтверждение email | Чекбокс | Вкл | Новые пользователи должны подтвердить email перед созданием аккаунта. При выключении аккаунт создается сразу. |
| Время жизни заявки (часы) | Число | 24 | Через сколько часов неподтвержденная заявка удаляется автоматически. |
Защита от спама
| Параметр | Тип | По умолчанию | Описание |
|---|---|---|---|
| Капча включена | Чекбокс | Вкл | Показывать капчу в форме регистрации. |
| Тип капчи | Выпадающий список | math | math -- математический пример (SVG-изображение), image_select -- выбор нужного эмодзи из набора. |
| Honeypot (скрытое поле) | Чекбокс | Вкл | Невидимое поле-ловушка. Если бот заполнит его, регистрация тихо "принимается" без реального создания заявки. |
| Ограничение по IP | Чекбокс | Вкл | Включить контроль числа попыток регистрации с одного IP-адреса. |
| Макс. попыток с одного IP | Число | 5 | Сколько заявок может быть создано с одного IP за указанное окно. |
| Окно (секунды) | Число | 3600 | Временное окно для подсчета попыток (по умолчанию 1 час). |
Архитектура
Структура файлов
lapsha-suspended-registration.php -- Главный файл плагина: константы, автозагрузка классов, хуки активации/деактивации, инициализация
uninstall.php -- Удаление данных при деинсталляции: опции, таблицы, cron
includes/
Admin.php -- Страница настроек в админке (Settings API)
Assets.php -- Подключение CSS и JS на фронтенде
Captcha.php -- Генерация и проверка капчи (math / image_select)
Cron.php -- Cron-задача для очистки просроченных записей
Database.php -- Создание таблиц, CRUD-операции для pending-пользователей и капчи
RateLimiter.php -- Рендеринг honeypot-поля
Registration.php -- Основная логика регистрации: валидация, сохранение заявки, отправка письма
Verification.php -- Обработка ссылки подтверждения, создание реального пользователя
assets/
css/lapsha-reg-front.css -- Стили капчи, honeypot, сообщений
js/lapsha-reg-front.js -- Загрузка капчи по AJAX, интеграция с формой, обработка ответа
Пространство имен
Все классы находятся в пространстве Lapsha\Reg. Автозагрузка реализована через spl_autoload_register в главном файле плагина.
Таблицы базы данных
При активации плагин создает две таблицы (с префиксом WordPress):
wp_lapsha_pending_users -- временные заявки на регистрацию:
| Поле | Тип | Описание |
|---|---|---|
| id | BIGINT UNSIGNED, AUTO_INCREMENT | Первичный ключ |
| VARCHAR(100), UNIQUE | Email пользователя | |
| username | VARCHAR(60) | Имя пользователя (если требуется настройками WooCommerce) |
| password_hash | VARCHAR(255) | Хеш пароля (если пользователь задал его вручную) |
| token | VARCHAR(64), UNIQUE | Токен подтверждения (64 hex-символа, 32 случайных байта) |
| ip_address | VARCHAR(45) | IP-адрес отправителя |
| created_at | DATETIME | Дата создания заявки |
| expires_at | DATETIME | Дата истечения (индексировано для быстрой очистки) |
wp_lapsha_captcha_challenges -- серверные записи капчи:
| Поле | Тип | Описание |
|---|---|---|
| id | BIGINT UNSIGNED, AUTO_INCREMENT | Первичный ключ |
| session_key | VARCHAR(64), UNIQUE | Идентификатор сессии капчи (32 случайных байта, hex) |
| challenge_data | TEXT | HTML-разметка вопроса |
| answer | VARCHAR(100) | Правильный ответ |
| created_at | DATETIME | Дата создания |
| expires_at | DATETIME | Дата истечения (10 минут) |
Процесс регистрации
С включенным подтверждением email (по умолчанию)
- Пользователь заполняет форму регистрации WooCommerce и нажимает "Зарегистрироваться".
- Фронтенд-скрипт через
$.ajaxPrefilterдополняет стандартный AJAX-запрос темы полями капчи и honeypot. - Плагин перехватывает AJAX-действие
ajaxreg(заменяя обработчик темы). - Последовательно выполняются проверки:
- Валидация email.
- Проверка honeypot (если заполнено -- тихий "успех" без создания заявки).
- Проверка rate limit по IP (подсчет заявок из таблицы
pending_users). - Проверка капчи (сверка ответа с записью в БД, запись удаляется после проверки).
- Проверка существования email среди реальных пользователей WordPress.
- Применение фильтра
woocommerce_process_registration_errorsдля совместимости.
- Создается запись в таблице
wp_lapsha_pending_usersс уникальным токеном. - На email отправляется письмо со ссылкой вида
https://site.com/?lapsha_action=verify&token=.... - Фронтенд получает JSON-ответ с флагом
pending: true, показывает сообщение об отправке письма и блокирует кнопку отправки.
Подтверждение email
- Пользователь переходит по ссылке из письма.
Verificationперехватывает запрос на хукеtemplate_redirect.- Токен валидируется: формат (64 hex-символа), наличие в БД, срок действия.
- Проверяется, что email не был занят другим пользователем за время ожидания.
- Создается реальный пользователь через
wc_create_new_customer(илиwp_create_userпри отсутствии WooCommerce). - Если пользователь задавал собственный пароль, хеш перезаписывается напрямую в таблице
wp_users. - Запись из
pending_usersудаляется. - Пользователь автоматически авторизуется и перенаправляется на страницу "Мой аккаунт".
Без подтверждения email
Если опция "Подтверждение email" выключена, аккаунт создается сразу через wc_create_new_customer. Пользователь авторизуется и получает JSON-ответ с loggedin: true.
Система капчи
Капча полностью автономная -- не зависит от сторонних сервисов. Все данные хранятся на сервере в таблице wp_lapsha_captcha_challenges.
Математический пример (math)
- Генерируется случайный пример: сложение (1-20), вычитание (результат всегда положительный) или умножение (2-9).
- Выражение рендерится как инлайновый SVG с рандомизированным поворотом символов и шумовыми линиями для усложнения машинного распознавания.
- Пользователь вводит числовой ответ в текстовое поле.
Выбор изображения (image_select)
- Из четырех категорий (животные, фрукты, транспорт, погода) случайно выбирается целевой эмодзи.
- Формируется набор из 6 вариантов: 1 правильный + 5 из других категорий.
- Пользователь кликает на нужный эмодзи, его индекс записывается в скрытое поле.
Общие свойства
- Каждая капча одноразовая: запись удаляется из БД сразу после проверки, независимо от результата.
- Ответ проверяется с использованием
hash_equals(защита от timing-атак). - Срок жизни записи -- 10 минут.
- Кнопка обновления позволяет получить новую капчу без перезагрузки страницы.
- После неудачной попытки регистрации капча автоматически перезагружается.
Защита от спама
Honeypot
Невидимое поле lapsha_website_url, скрытое через CSS (position: absolute; left: -9999px). Боты, заполняющие все поля формы, попадают в ловушку. При заполненном honeypot плагин возвращает ответ об успешной регистрации, не создавая заявку.
Ограничение по IP
Подсчитывается количество записей в pending_users с данного IP за настраиваемое временное окно. При превышении лимита возвращается ошибка. IP-адрес определяется из $_SERVER['REMOTE_ADDR'] с валидацией через filter_var.
Cron
При активации плагина регистрируется ежечасная задача lapsha_cleanup_pending_users. Задача удаляет:
- Записи из
wp_lapsha_pending_usersс истекшимexpires_at. - Записи из
wp_lapsha_captcha_challengesс истекшимexpires_at.
При деактивации плагина cron-задача снимается с расписания.
Фронтенд
CSS и JS подключаются только для неавторизованных пользователей и только при включенном плагине.
JavaScript выполняет:
- Запрос капчи через AJAX (
action=lapsha_captcha) при загрузке страницы. - Обработку кликов по эмодзи в режиме
image_select. - Инъекцию полей капчи и honeypot в AJAX-запрос регистрации темы через
$.ajaxPrefilter. - Перехват ответа: при получении
pending: trueпоказывается сообщение о необходимости подтвердить email, кнопка блокируется. - Автоматическую перезагрузку капчи после неудачной попытки.
Удаление
При полном удалении плагина через админку WordPress (файл uninstall.php):
- Удаляются все опции плагина из таблицы
wp_options. - Удаляются таблицы
wp_lapsha_pending_usersиwp_lapsha_captcha_challenges. - Снимается cron-задача
lapsha_cleanup_pending_users.
Совместимость
- Плагин интегрируется с WooCommerce через стандартные хуки:
woocommerce_register_form,woocommerce_process_registration_errors,wc_create_new_customer,wc_set_customer_auth_cookie. - Перехват AJAX-регистрации рассчитан на темы, использующие действие
ajaxregдля регистрации (например, темы с кастомнымajax-reg-script.js). - При отсутствии WooCommerce плагин использует
wp_create_userиwp_set_auth_cookieкак запасной вариант.
Лицензия
Автор: Lapsha Dev (https://lapsha.dev) Версия: 1.0.0-alpha.4