Как выбрать API для решения капчи: от каталогов типов до циклов проверки в собственных системах
Проверяйте типы, параметры и формат результата в собственных системах и с помощью официальных тестовых механизмов. Разделяйте приём токенов, серверную валидацию, бизнес-операции и затраты, чтобы не принимать возвращённое значение за успешную валидацию.
При интеграции капчи самая опасная ошибка обычно связана не с выбором неверного названия, а с приравниванием «результат получен» к «проверка пройдена». Получение клиентом непустого токена, принятие этого токена сервисом проверки и разрешение операции бизнес-логикой — три разных события. Если проверить только первое, бэкенд всё равно может отклонить отправку формы; если сразу приравнять первое событие к третьему, можно обойти внутреннюю проверку прав доступа.
Это руководство рассчитано на разработку и тестирование в собственных системах: как определить продукт защиты, изучить актуальные параметры и формат ответа для типов EveryInfra, изолировать тестовые конфигурации и убедиться, что при сбое система останавливается в правильном состоянии. Оно также применимо к официальным тестовым средам и явно разрешённым областям тестирования. В статье нет инструкций по работе с реальными сторонними аккаунтами, платежами, правами доступа или проверками в рамках управления рисками.
Определите, что тестировать в первую очередь
Если нужно лишь убедиться, что форма сохраняет данные после успешной валидации и блокирует запись при ошибке, в первую очередь используйте официальные тестовые механизмы продукта защиты. Они дают контролируемые результаты, и каждый запуск CI не превращается в решение реальной капчи. Ещё один API на этом этапе не добавляет пользы для тестирования, а лишь создаёт дополнительную зависимость, которую нужно отдельно проверять.
Если нужно оценить возможности EveryInfra по решению капчи, разделите тест на два независимых вопроса: соответствуют ли входные и выходные данные API согласованному формату и правильно ли обрабатываются возвращённые значения в разрешённых средах. Храните доказательства по каждому вопросу отдельно и не подменяйте успех одного успехом другого. Выбор начинается с тестовой задачи, а не с количества типов в каталоге.
Определяйте продукт по конфигурации интеграции, а не по внешнему виду
Подтверждайте продукт, режим, домены и сценарии использования по коду интеграции, конфигурации бэкенда и соответствующей официальной документации для своих страниц. Один лишь внешний вид чекбокса не определяет тип запроса, а разные режимы одного продукта нельзя произвольно подменять. Ведите понятный журнал тестирования: кому принадлежит страница, что разрешено тестировать, какие тестовые конфигурации используются и каких результатов вы ожидаете.
Для сред, на тестирование которых у вас есть разрешение, но которые вы не обслуживаете, параметры должен предоставить ответственный за среду либо их следует получить из документации в рамках разрешённого доступа. Если контекста не хватает, остановитесь и запросите подтверждение у ответственного за среду; никогда не позволяйте программам угадывать похожие типы или придумывать поля. Наличие публичного идентификатора на странице не даёт разрешения на произвольные автоматизированные действия.
Например, конфигурация hostname в Turnstile принимает доменные имена без протокола, порта и пути, а указание родительского домена охватывает его поддомены. Границы тестовых сред должны подтверждать ответственные за них специалисты; не ослабляйте конфигурацию ради принятия неверного адреса. Это отличается от полей website_url в запросах.
Изучите типы, доступность, параметры и формат результата
Ниже показано бесплатное чтение каталога без аутентификации, при котором не создаются задачи на решение капчи. В примере выбраны только два типа, чтобы сравнить их параметры и форматы ответа; это не значит, что нужно работать с обоими типами проверок. Нужны curl и jq. Если чтение каталога завершится ошибкой, сначала разберитесь с этапом определения доступных типов и не переходите к рабочим запросам с пустыми результатами этого этапа.
set -o pipefail
curl -fsS --max-time 30 'https://api.everyinfra.com/api/v1/captcha/types' \
| jq -e '[.types[] |
select(.type == "turnstile" or .type == "recaptcha_grid") |
{type, available, required_params, optional_params, solution}
] | if length == 2 then . else error("expected types missing") end'При публичной проверке 2026/9/4 обязательными параметрами для turnstile были website_url и website_key, а среди необязательных были action, cdata и page_data; solution.shape имел значение token, поле — token. Для recaptcha_grid обязательными параметрами были body и question, shape — points, поле — objects. На тот момент оба типа были доступны. Это декларация каталога, а не доказательство успешного решения реальной проверки.
Поэтому обработчики результатов должны ветвиться по проверенному типу и формату solution, а не безусловно брать токен верхнего уровня или приводить произвольные объекты к строкам. Наличие параметра в optional_params означает лишь, что каталог объявляет его необязательным; успех конкретной комбинации зависит от текущих ошибок и доступности, и его нельзя добиваться, убирая важные бизнес-ограничения.
Сохраняйте время наблюдения вместе с выбранными записями. Не отправляйте задачи, если available равно false; при отсутствии полей, неверных типах или ошибках чтения считайте состояние неизвестным и остановитесь. Даже если available равно true, это означает лишь, что в момент наблюдения можно было попытаться использовать эту возможность; успех последующих задач не гарантирован.
Изолируйте официальные тестовые механизмы от рабочих конфигураций
Cloudflare Turnstile предоставляет тестовые sitekey и secret, позволяющие имитировать успешную и неуспешную проверку, а также уже использованные токены. Тестовые и рабочие токены или ключи нельзя смешивать. В FAQ Google reCAPTCHA описаны отдельные тестовые ключи для v2 и тестовые конфигурации для v3; оценки v3 в тестовой среде нельзя использовать как показатель эффективности оценки рисков на реальном трафике.
Sitekey — это публичный идентификатор, который использует страница, а secret — ключ для валидации на бэкенде. Тестовые конфигурации должны браться из явных настроек окружения; нельзя переключаться на поведение «всегда успешно» лишь потому, что запрос называет себя тестовым. При запуске в продакшене проверяйте источники конфигурации и согласованность окружения; в логах храните только необходимые для аудита состояния и не выводите secret, полные токены или исходные объекты запросов.
Скройте сервис валидации за узким интерфейсом в бизнес-коде: бизнес-логика получает явный результат проверки, а тесты могут подставлять синтетические результаты. Реальная внешняя валидация по-прежнему выполняется на сервере. Механизм подстановки должен управляться только тестовыми сборками или конфигурацией сервера и никогда не должен быть доступен пользователю как параметр запроса. Это рекомендация по проектированию приложения, а не автоматическая функция EveryInfra.
Разделяйте приём токенов, серверную проверку и бизнес-логику
Turnstile официально требует серверного вызова Siteverify; одного фронтенд-компонента недостаточно для полной защиты. Согласно официальной документации, токен действителен пять минут и может быть проверен только один раз. Не считайте токены учётными данными, которые можно долго кешировать или использовать повторно, и не пытайтесь восстановиться после сетевых сбоев бесконечными повторными попытками с тем же значением.
Даже после успешной серверной валидации бизнес-логика должна проверять сессию, права на ресурс, входные данные и защиту от повторной отправки. Капча не является ни учётными данными аккаунта, ни авторизацией транзакции. Если последующие шаги завершаются ошибкой, сохраняйте бизнес-ошибку и не переименовывайте её в «ошибку капчи», порождая бесконечные новые задачи.
Детали проверки нельзя переносить между продуктами. В документации Google reCAPTCHA по валидации на бэкенде указано правило одноразового токена со сроком действия две минуты и ошибки вроде timeout-or-duplicate, что отличается от пятиминутного окна Turnstile. Обработку ошибок нужно привязывать к конкретному продукту и фактическим ответам валидации.
Проверьте условия приёма на бэкенде на офлайн-примерах
Ниже приведена проверка результатов для собственной тестовой страницы. На странице явно заданы hostname со значением localhost и action со значением test; ожидаемые значения берутся из фиксированной конфигурации сервера, а не из пользовательских запросов. В реальной интеграции входящие результаты должен получать ваш собственный сервер, вызывая официальные эндпоинты проверки; никогда не доверяйте вслепую успеху, о котором сообщает клиент.
function acceptOwnTestVerification(result, expected) {
if (!expected || typeof expected.hostname !== "string" ||
!expected.hostname.trim() || typeof expected.action !== "string" ||
!expected.action.trim()) {
throw new Error("server-side test configuration required");
}
if (!result || typeof result !== "object" || Array.isArray(result)) {
return { accepted: false, reason: "invalid_response" };
}
if (result.success !== true) {
return { accepted: false, reason: "verification_failed" };
}
if (result.hostname !== expected.hostname) {
return { accepted: false, reason: "hostname_mismatch" };
}
if (result.action !== expected.action) {
return { accepted: false, reason: "action_mismatch" };
}
return { accepted: true, reason: "verification_only" };
}
// all values are self-made test fixtures; no network requests, no tokens held or generated.
const expected = { hostname: "localhost", action: "test" };
const synthetic = { success: true, hostname: "localhost", action: "test" };
console.log(acceptOwnTestVerification(synthetic, expected));
// { accepted: true, reason: 'verification_only' }Этот пример выводит verification_only: он не выдаёт токены, не вызывает Siteverify и не отправляет формы. Проверка требует action, потому что этого явно требует данная тестовая конфигурация; не рассчитывайте, что все продукты защиты возвращают одинаковые поля. Реализуйте правила валидации для каждого продукта отдельно, а не используйте одну обобщённую функцию с ослабленными проверками.
Отдельно протестируйте success: true, success: false, строковые значения success, ошибки домена, отсутствие action, пустые ответы и отсутствие конфигурации сервера. Затем проверьте весь путь от страницы до собственного бэкенда в рамках разрешённой тестовой интеграции. Прохождение офлайн-функций доказывает только корректность решений в этих ветвях, но не сетевую проверку, рабочие конфигурации или эффективность распознавания рисков.
Определяйте следующий шаг по месту сбоя
- Этап ввода: несовпадающие типы, отсутствующие обязательные значения или неподдерживаемые комбинации параметров. Сначала исправьте параметры; не повторяйте одинаковые запросы в цикле.
- Этап проверки возможности: нет достоверных данных каталога или возможность сейчас недоступна. Остановите тестирование и зафиксируйте наблюдения, не заменяя один продукт защиты другим без оснований.
- Этап вызова: фиксируйте явные ошибки и тайм-ауты отдельно. Неполученный результат не означает, что сервер не выполнил запрос; в первую очередь сохраните идентификаторы корреляции запроса.
- Этап валидации: ваш бэкенд отклоняет результаты. Фиксируйте безопасную классификацию ошибок и соответствующие тестовые случаи, проверяйте окружение, домены и action, а не ослабляйте критерии приёма.
- Бизнес-этап: проверка пройдена, но запросы всё равно отклоняются из-за входных данных, прав или повторной отправки. Обрабатывайте такие случаи в рамках бизнес-процессов, не считая, что капча осталась нерешённой.
Затраты тоже нужно сверять по этим уровням. Текущая реализация EveryInfra включает ветви возврата средств в учёте после неудачного решения капчи, однако ошибка проверки на стороне клиента или отказ бизнес-логики не означают, что шлюз зафиксировал неудачное решение капчи. Не делайте выводов о возврате средств или восстановлении резерва только по красному тексту на фронтенде; сверяйте данные по одним и тем же запросам, используя ответы на вызовы API и доступные записи биллинга. В статье нет новых примеров восстановления баланса после реальных сбоев, и она не обещает, что любые последующие отказы меняют состояния учёта.
Оставляйте записи тестов, которые можно проверить
Полезная запись о приёмке содержит: разрешённые среды, режимы продукта, время наблюдения, категории тестовых конфигураций, структуру входных данных, структуру ответа, решение по валидации, бизнес-решение и решение по биллингу. По возможности не включайте реальное содержимое и связывайте результаты уровней через маскированные ID корреляции. Явно указывайте, что не покрыто, чтобы следующие команды не приняли «каталог успешно прочитан» за полную приёмку.
Проверьте собственные сценарии успеха и неудачи с помощью официальных тестовых механизмов, оцените нужные ветки API и только потом расширяйте проверку в разрешённых рамках. Критерий выбора типа капчи — не похожее название и не непустой ответ, а понятные входные условия, интерпретируемый формат ответа, корректные решения на бэкенде и обработка сбоев, не выходящая за бизнес-границы.
Справочник LF-15