Как решить reCAPTCHA v3 в Node.js и задать action

solve recaptcha v3 in node.js - How to Solve reCAPTCHA v3 in Node.js and Set an Action

reCAPTCHA v3 никогда не показывает головоломку. Она молча оценивает визит и передаёт странице токен, который сайт проверяет на своём бэкенде. С вашей стороны нажимать нечего, поэтому вся задача сводится к получению токена, который сайт примет. В Node.js это тот же recaptcha метод, используемый для v2, с одной дополнительной опцией.

Деталь, от которой зависит, сработает ли это, — это action.

Настройка

npm install capskip
const { CapSkip } = require('capskip');

const solver = new CapSkip({
  host: '127.0.0.1',
  port: 8080,
  recaptchaTimeout: 300,   // seconds, shared with Turnstile and GeeTest
});

CapSkip работает локально, поэтому десктопное приложение должно быть открыто, прежде чем любой вызов сработает.

Базовый вызов

const result = await solver.recaptcha(
  '6Lc...YOUR_SITEKEY',
  'https://example.com/checkout',
  { version: 'v3', action: 'submit' },
);

console.log(result.code);   // the v3 token

Два отличия от v2: version: 'v3' обязателен, и action должно совпадать с тем, что страница передаёт в grecaptcha.execute. Опустите его, и по умолчанию будет verify.

Почему действие имеет значение

Actions (действия) — это метки, которые сайт присваивает каждому защищённому взаимодействию, чтобы вход и оформление заказа могли оцениваться независимо. Большинство бэкендов проверяют, что действие в токене совпадает с тем, которое они ожидали для этого эндпоинта.

Отправьте неверную метку — и токен будет подлинным, но придёт помеченным для другого взаимодействия, что многие верификаторы отклоняют. Считывайте настоящее значение со страницы, а не угадывайте:

const html = await (await fetch('https://example.com/checkout')).text();

// Sites normally call execute() with the action as a string literal.
const match = html.match(/execute\([^,]+,\s*\{\s*action:\s*['"]([^'"]+)/);
const action = match ? match[1] : 'verify';

const result = await solver.recaptcha(sitekey, pageUrl, {
  version: 'v3',
  action,
});

Обычные значения — login, submit, homepage и checkout, но это произвольные строки, выбранные тем, кто создавал сайт.

Enterprise v3

const result = await solver.recaptcha(sitekey, pageUrl, {
  version: 'v3',
  enterprise: 1,
  action: 'submit',
});

Enterprise — это ортогональный флаг, а не отдельный продукт, поэтому он просто добавляется. Различить их можно по скрипту, который загружает страница: Enterprise подгружает enterprise.js, стандартный извлекает api.js. Неверная догадка приводит к сбою решения, а не к возврату плохого токена, поэтому проверка обходится дёшево.

Отправка токена

const response = await fetch('https://example.com/checkout', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    token: result.code,
    orderId: '...',
  }),
});

В отличие от v2, здесь нет стандартного виджета формы, поэтому интеграции v3 различаются. Некоторые используют скрытый g-recaptcha-response поле, другие отправляют JSON с пользовательским ключом. Проверьте, что делает собственный JavaScript страницы, прежде чем предполагать имя поля.

Массовое решение

const tokens = await Promise.all(
  urls.map((url) =>
    solver.recaptcha(sitekey, url, { version: 'v3', action: 'submit' })),
);

console.log(tokens.map((t) => t.code));

AsyncCapSkip также существует в этом пакете, но это псевдоним CapSkip. Каждый метод уже возвращает Promise, поэтому Promise.all — это вся история про параллелизм в Node.

Ошибки

const { ApiException, NetworkException } = require('capskip');

try {
  const result = await solver.recaptcha(sitekey, pageUrl, { version: 'v3' });
} catch (err) {
  if (err instanceof NetworkException) {
    // CapSkip is not running on the configured port
  } else if (err instanceof ApiException) {
    // the sitekey or pageurl was rejected
  } else {
    throw err;
  }
}

Часто задаваемые вопросы

Могу ли я увидеть оценку перед отправкой?

Нет. Балл остаётся у Google и раскрывается владельцу сайта только тогда, когда его бэкенд проверяет токен. На стороне клиента вы получаете токен и ничего больше, поэтому проверить или отфильтровать по баллу заранее невозможно.

Что если на странице нет видимого action?

Некоторые страницы вызывают execute без него, и в этом случае по умолчанию verify верно. Если приведённое выше регулярное выражение ничего не находит, обычно причина именно в этом, а не в ошибке разбора.

Как долго действует токен v3?

Примерно две минуты, одноразовый, как и у v2. Решайте непосредственно перед запросом, которому он нужен, а не накапливайте пул.

Сводка

Передать version: 'v3', установите action на то, что страница на самом деле выполняет, добавьте enterprise: 1 когда она загружается enterprise.js, и отправляйте быстро, потому что токен истекает примерно через две минуты.

Другие языки рассматриваются на решение для reCAPTCHA v3 странице, специфика Enterprise — на Сервис распознавания Enterprise страница, а более широкий набор для Node — Сервис распознавания капчи для Node.js страница. Посмотрите, как настоящий токен появляется на нашей демо v3. CapSkip — это распознавание капчи который работает на вашем собственном компьютере.