Как решить reCAPTCHA v3 на PHP и задать action

reCAPTCHA v3 никогда не показывает задачу. Она незаметно оценивает визит и выдаёт странице токен, который затем проверяет backend сайта. Для вашего кода это значит, что кликать не по чему, поэтому вся задача сводится к тому, чтобы получить токен, который примет сайт. В PHP это тот же самый recaptcha метод, который вы использовали бы для v2, с флагом версии в массиве options.
От чего зависит, сработает ли это, — так это action.
Настройка
# PHP 8.0+, with the curl and json extensions. composer require capskip/capskip
use CapSkip\CapSkip;
$solver = new CapSkip([
'host' => '127.0.0.1',
'port' => 8080,
'recaptchaTimeout' => 300, // seconds, shared with Turnstile and GeeTest
]);CapSkip работает на вашем компьютере, поэтому сначала должно быть открыто десктопное приложение.
Базовый вызов
$result = $solver->recaptcha(
'6Lc...YOUR_SITEKEY',
'https://example.com/checkout',
[
'version' => 'v3',
'action' => 'submit',
]
);
echo $result['code']; // the v3 tokenДва отличия от v2. version должен быть v3, и action должен совпадать с тем, что страница передаёт в grecaptcha.execute. Опустите его, и по умолчанию будет verify.
Почему действие имеет значение
Action — это метки, которые сайт присваивает каждому защищённому взаимодействию, чтобы вход и оформление заказа могли оцениваться отдельно. Большинство бэкендов проверяют, что action, содержащийся в токене, совпадает с тем, который они ожидали для этого эндпоинта.
Отправьте неверную метку — и токен будет настоящим, но помеченным для другого взаимодействия, что многие проверяющие системы отклоняют сразу. Считывайте реальное значение со страницы, а не угадывайте:
$html = file_get_contents('https://example.com/checkout');
// Sites normally call execute() with the action as a string literal.
preg_match('/execute\([^,]+,\s*\{\s*action:\s*[\'"]([^\'"]+)/', $html, $m);
$action = $m[1] ?? 'verify';
$result = $solver->recaptcha($sitekey, $pageUrl, [
'version' => 'v3',
'action' => $action,
]);Обычные значения — login, submit, homepage и checkout, но это произвольные строки, выбранные тем, кто создавал сайт.
Enterprise v3
$result = $solver->recaptcha($sitekey, $pageUrl, [
'version' => 'v3',
'enterprise' => 1,
'action' => 'submit',
]);Enterprise — это ортогональный флаг, а не отдельный продукт, поэтому он накладывается на вызов v3. Различайте их по скрипту, который загружает страница: Enterprise подгружает enterprise.js, стандартный извлекает api.js. Неверная догадка приводит к сбою решения, а не к возврату плохого токена, поэтому проверить ничего не стоит.
Отправка токена
$ch = curl_init('https://example.com/checkout');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
CURLOPT_POSTFIELDS => json_encode([
'token' => $result['code'],
'order_id' => '...',
]),
]);
$response = curl_exec($ch);
curl_close($ch);В отличие от v2, здесь нет стандартного виджета формы, ограничивающего структуру, поэтому интеграции v3 различаются. Некоторые используют скрытое g-recaptcha-response input, другие отправляют JSON с пользовательским ключом. Проверьте собственный JavaScript страницы, прежде чем предполагать имя поля.
Ошибки
use CapSkip\Exceptions\ApiException;
use CapSkip\Exceptions\NetworkException;
use CapSkip\Exceptions\TimeoutException;
try {
$result = $solver->recaptcha($sitekey, $pageUrl, ['version' => 'v3']);
} catch (NetworkException $e) {
// CapSkip is not running on the configured port
} catch (ApiException $e) {
// the sitekey or pageurl was rejected
} catch (TimeoutException $e) {
// exceeded recaptchaTimeout
}Обратите внимание на CapSkip\Exceptions пространство имён. Копирование импортов из примеров для Python или Node — частый источник фатальных ошибок здесь.
Часто задаваемые вопросы
Могу ли я проверить оценку перед отправкой?
Нет. Score хранится у Google и раскрывается владельцу сайта только когда его backend проверяет токен. На стороне клиента вы получаете лишь токен и ничего больше, поэтому заранее нечего проверять или фильтровать.
Стоит ли решать капчу внутри веб-запроса?
Желательно нет. PHP синхронен, а решение может занять несколько секунд, поэтому выполнение его во время рендеринга страницы занимает воркер на всё это время. Вынесите его в задачу очереди или в CLI-воркер.
Что, если страница вообще не задаёт action?
Некоторые страницы вызывают execute без него, и в этом случае по умолчанию verify верен. Если ваше регулярное выражение ничего не находит, обычно причина именно в этом, а не в ошибке парсинга.
Сводка
Установить version в v3, сопоставьте action к тому, что выполняет страница, добавьте enterprise когда она загружается enterprise.js, импортируйте исключения из CapSkip\Exceptions, и отправляйте токен быстро, потому что он истекает примерно через две минуты.
Другие языки рассматриваются на решение для reCAPTCHA v3 странице, детали Enterprise на Сервис распознавания Enterprise страница, а более широкий охват PHP — на Решатель капчи для PHP страница. Посмотрите, как токен генерируется вживую на нашей демо v3. CapSkip — это распознавание капчи который работает на вашем оборудовании.
