Формы обратной связи кажутся небольшой частью сайта, но именно они постоянно доступны извне и принимают данные от любого посетителя. Этим пользуются не только реальные пользователи, но и автоматические боты.
Если форма не защищена, ее можно отправлять автоматически множество раз. В результате в почте, CRM или других системах начинают появляться мусорные обращения, а сервер обрабатывает запросы, которые не имеют отношения к реальным клиентам.
Зачем вообще защищать формы
Основная задача защиты формы - отличить нормальное пользовательское действие от автоматической отправки.
Проблема особенно заметна на сайтах, где форм много. Например, отдельно могут существовать запрос цены, обращение по товару, форма поставщика, отправка резюме, экспортная заявка и обычная обратная связь.
Для бизнеса спам в формах - это не только техническая проблема. Каждое ложное обращение может попасть в почту или CRM, после чего сотруднику приходится определить, есть ли за ним реальный человек. Чем больше таких заявок, тем больше ручной работы и тем выше риск пропустить настоящее обращение.
Какие способы защиты существуют
Защита форм обычно строится из нескольких уровней. Одного универсального способа, который решает все задачи, нет.
- Ограничение частоты запросов. Сервер может ограничивать количество отправок с одного источника за определенный период.
- Honeypot. В форму добавляется скрытое поле, которое обычный пользователь не заполняет, а простой бот может заполнить автоматически.
- Проверка данных на сервере. Даже если браузерная валидация была обойдена, сервер должен самостоятельно проверять полученные данные.
- Фильтрация на уровне сервера или WAF. Подозрительные запросы можно блокировать еще до обработки самой формой.
- CAPTCHA. Пользователь подтверждает, что действие выполняется человеком, либо система анализирует дополнительные признаки запроса.
На практике эти способы лучше комбинировать. CAPTCHA не заменяет серверную валидацию и другие ограничения, но хорошо подходит как дополнительный барьер для публичных форм.
Почему выбрали Yandex SmartCaptcha
Для проекта требовалась понятная пользователю проверка, которую можно подключить к нескольким формам сайта.
Использовали Yandex SmartCaptcha в варианте с чекбоксом «Я не робот». Пользователь проходит проверку, после чего форма получает специальный токен.
Сам факт появления токена в браузере еще нельзя считать достаточной защитой. Перед обработкой заявки токен дополнительно проверяется на сервере. Только после успешной проверки данные формы обрабатываются дальше.
Почему не стали добавлять CAPTCHA в каждую форму отдельно
Самый простой вариант - открыть каждый шаблон формы и добавить туда виджет SmartCaptcha, JavaScript и проверку результата.
Для одной формы это нормальное решение. Но когда форм становится несколько, появляется повторяющийся код.
При таком подходе в нескольких местах приходится отдельно контролировать подключение скрипта CAPTCHA, настройки, получение токена, серверную проверку, вывод ошибок и поведение после AJAX-отправки.
Кроме того, при появлении новой формы разработчику приходится снова подключать всю эту механику.
Единый механизм вместо набора отдельных интеграций
Поэтому SmartCaptcha вынесли в общий механизм, который работает поверх существующих форм сайта.
Форма остается самостоятельным компонентом и продолжает отвечать за свои поля и данные. Общий слой берет на себя то, что должно работать одинаково везде: CAPTCHA, базовую валидацию и обработку связанных ошибок.
В результате одна логика используется сразу несколькими формами.
- SmartCaptcha подключается централизованно.
- Настройки не дублируются по шаблонам.
- Перед отправкой проверяется наличие успешной CAPTCHA.
- Токен проверяется на сервере.
- Ошибки отображаются одинаково.
- AJAX-формы корректно переинициализируются.
- После успешной отправки виджет больше не остается на странице.
Заодно унифицировали валидацию
Если CAPTCHA работает одинаково, но каждая форма по-разному сообщает пользователю об ошибках, проблема решена только частично.
Поэтому вместе с защитой привели формы к общей логике валидации.
- обязательные поля отмечаются до отправки;
- для незаполненного поля показывается понятная причина ошибки;
- телефон и email проверяются отдельно;
- сообщение выводится непосредственно под проблемным полем;
- при отправке пользователь переводится к первой найденной ошибке;
- согласие на обработку данных проверяется по тем же правилам во всех формах.
Так пользователь взаимодействует с формами одинаково независимо от того, где именно на сайте они находятся.
Контекст заявки тоже важен
Одна и та же форма может использоваться на разных страницах. Например, пользователь может открыть ее из карточки конкретного продукта.
Поэтому вместе с заявкой автоматически передается полный адрес страницы, с которой была выполнена отправка.
В результате сотрудник получает не только введенные пользователем данные, но и контекст обращения. Для этого не нужно создавать отдельную форму для каждой страницы.
Почему такой подход удобнее в поддержке
Главное преимущество единого механизма проявляется не в момент первого внедрения, а позже.
Если меняется логика проверки, оформление ошибки или способ подключения CAPTCHA, изменение можно выполнить централизованно. Не требуется вспоминать, в каких шаблонах была скопирована одна и та же логика.
То же относится к новым формам. Вместо полноценной повторной интеграции достаточно подключить форму к уже существующему механизму.
Результат
В итоге CAPTCHA перестала быть частью конкретной формы и стала общим сервисным слоем сайта.
Получилась единая схема: форма пользователя - клиентская валидация - SmartCaptcha - серверная проверка - обработка заявки.
Такой подход не отменяет остальные способы защиты, например ограничения частоты запросов или серверную фильтрацию. Но он позволяет централизованно закрыть одну из основных задач публичных форм - автоматическую отправку заявок ботами.
Ценность
Вместо нескольких независимых реализаций сайт получает один поддерживаемый механизм защиты форм.
Это уменьшает количество дублирующегося кода, упрощает подключение новых форм, делает поведение интерфейса предсказуемым и снижает вероятность того, что одна из публичных форм останется без актуальной защиты.