Защита от СПАМа AjaxForm

Данное решение было написано спонтанно, так как заказчику требовалось срочно решить проблему со СПАМом, а рекапчу и вовсе хотелось убрать. Посмотрев, что уже было сделано, понял, что скрытое поле, которое должен был заполнить Бот и на этом попасться уже использовали, а рекапчу хотят убрать, применил такое решение:
В форму добавляется скрытое поле. При загрузке страницы, происходит ajax запрос на сервер и получается уникальный код. Ajax запрос отсечет ботов, которые не открывают страницу в браузере, а соответственно и не выполняют javascript код. Генерируемый сервером код, также помещаем в переменную сессии и при валидации формы сверяем заполненный код и код из сессии.

Для этих целей был написан кастомный валидатор, хук и небольшой кусок кода.

UPDATE 29 сентября 2019
Оформил в виде пакета stopspam. Устанавливаем его локально. Добавляем тег к форме
<input type="hidden" name="xcode" value="1" />
и добавления валидаторов в вызов AjaxForm
{$_modx->runSnippet('!AjaxForm', [
        'snippet'=>'FormIt',
        'formName' => 'Заказ дизайн проекта',
        'validationErrorMessage' => 'Форма содержит ошибки',
        'formSelector' => 'af_service',
        'emailTo'=> $_modx->config.emailto,
        'emailSubject'=>$_modx->config.http_host ~ ' - Заказ дизайн проекта',
        'emailFrom'=>$_modx->config.emailsender,
        'emailFromName'=>$_modx->config.site_name,
        'form'=>'service.form',
        'emailTpl'=>'service.emailTpl',
        'hooks'=>'stopspam,email,FormItSaveForm',
        'customValidators'=>'isXcode',
        'validate'=>'message:required,name:required,phone:required,agree:required,xcode:isXcode',
    ])}

Прошлый текст ручной установке оставлю как прежде.

Добавляем 2 сниппета
Имя: isXcode
Содержимое:
<?php
if ($_SESSION['xcode'] != $value) {
    $validator->addError($key,'Не верный код антиспама');
    return false;
} else {
    return true;
}

Имя: stopspam
Содержимое:
<?php
if (!isset($_SESSION['xcode'])) {
    return false;
}

if ($_SESSION['xcode'] != $hook->getValue('xcode')) {
    $hook->addError('error_message','Вы идентифицированны как робот. Проверьте, что ваш браузер поддержкивает использование cookie');
    return false;
} else {
    return true;
}

JavaScript код для установки переменной:
$(document).ready(function(){
    $.ajax({
      url : "/assets/components/stopspam/action.php",
      dataType : "html",
      success : function(data) {
        $('[name="xcode"]').val(data);
      }
    });
});

и содержимое /assets/components/stopspam/action.php
<?php
define('MODX_API_MODE', true);
require_once $_SERVER['DOCUMENT_ROOT'] . '/index.php';

$modx->getService('error','error.modError');
$modx->setLogLevel(modX::LOG_LEVEL_ERROR);
$modx->setLogTarget('FILE');
if ($_SERVER['HTTP_X_REQUESTED_WITH'] != 'XMLHttpRequest') {
    $modx->sendRedirect($modx->makeUrl($modx->getOption('site_start'),'','','full'));
}

session_start();
if (empty($_SESSION['xcode'])) {
    $session_id = uniqid();
    $_SESSION['xcode'] = $session_id;   
} else {
    $session_id = $_SESSION['xcode'];
}

echo $session_id;
?>

Вызов формы будет выглядеть, например, так
{$_modx->runSnippet('!AjaxForm', [
        'snippet'=>'FormIt',
        'formName' => 'Заказ дизайн проекта',
        'validationErrorMessage' => 'Форма содержит ошибки',
        'formSelector' => 'af_service',
        'emailTo'=> $_modx->config.emailto,
        'emailSubject'=>$_modx->config.http_host ~ ' - Заказ дизайн проекта',
        'emailFrom'=>$_modx->config.emailsender,
        'emailFromName'=>$_modx->config.site_name,
        'form'=>'service.form',
        'emailTpl'=>'service.emailTpl',
        'hooks'=>'stopspam,email,FormItSaveForm',
        'customValidators'=>'isXcode',
        'validate'=>'message:required,name:required,phone:required,agree:required,xcode:isXcode',
    ])}

В html код формы добавляем input, с каким-нибудь значением
<input type="hidden" name="xcode" value="1" />

Нет комментариев