Используйте сервис решения CAPTCHA в Express

Автор: solvethree3 мин на чтение

Размещайте клиент solvethree на сервере Express. Используйте POST-маршрут с проверкой аутентификации для создания задачи и GET-маршрут для её получения. Зафиксируйте целевой ресурс и прокси в конфигурации сервера, чтобы вызывающие стороны не могли превратить эндпоинт в произвольный платный ретранслятор.

На этой странице

Настройте сервер и целевой сайт

Используйте Node.js 22 или новее и Express 5. Установите официальный JavaScript SDK из tarball-архива, как описано в документации, не предполагая, что он опубликован в реестре npm. В примере один клиент Solvethree создаётся вне обработчиков.

  • SOLVETHREE_API_KEY: API-ключ вашего рабочего пространства. Храните его на сервере.
  • INTEGRATION_KEY: отдельный секрет для доверенных внутренних вызывающих сторон. В примере он требуется в заголовке x-integration-key; не передавайте его браузерным клиентам. Если у вас уже есть промежуточное ПО аутентификации, используйте его вместо проверки общего ключа из примера.
  • CAPTCHA_SITE: имя хоста целевого ресурса, а не полный URL. Настройте активный профиль сайта для вашего рабочего пространства перед созданием задач; передача имени хоста не создаёт профиль.
  • SOLVETHREE_PROXY: прокси для этого целевого ресурса. В примере передаётся один прокси, а действие фиксировано как login. Измените это действие на сервере, если ваш целевой ресурс использует другое.

Этот запрос использует конфигурацию reCAPTCHA Enterprise по умолчанию. Ему нужны site, action и прокси, а не type или url. Если целевой ресурс ещё не настроен, см. настройку профиля сайта.

Создайте задачу один раз, затем получайте её данные

Express · создание и получение задач с аутентификацией
// npm install express and the official solvethree SDK tarball.
import express from 'express';
import { Solvethree, SolvethreeError } from '@solvethree/sdk';
const app = express();
const client = new Solvethree({ apiKey: process.env.SOLVETHREE_API_KEY });
const secret = process.env.INTEGRATION_KEY;
if (!secret) throw new Error('Set INTEGRATION_KEY');
app.use((request, response, next) => {
  if (request.get('x-integration-key') !== secret) return response.sendStatus(401);
  next();
});
app.post('/captcha/tasks', async (request, response) => {
  const task = await client.createTask({
    site: process.env.CAPTCHA_SITE, action: 'login', proxy: process.env.SOLVETHREE_PROXY,
    requestId: request.get('x-request-id'),
  }, { waitMs: 0, signal: AbortSignal.timeout(20000) });
  response.json(task);
});
app.get('/captcha/tasks/:id', async (request, response) => {
  response.json(await client.getTask(request.params.id, { waitMs: 15000, signal: AbortSignal.timeout(25000) }));
});
app.use((error, request, response, next) => {
  if (error instanceof SolvethreeError) return response.status(502).json({ requestId: error.requestId, taskId: error.taskId });
  response.status(400).json({ error: 'Invalid task input or ID' });
});
app.listen(3000);

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

  1. 1.

    Назначьте ID запроса перед созданием

    Передавайте x-request-id, содержащий 1–64 ASCII-буквы, цифры, символы подчёркивания или дефисы. Сохраняйте его вместе с логическим запросом, чтобы восстановить результат создания при истечении времени ожидания соединения.

  2. 2.

    Отправьте POST на /captcha/tasks один раз

    Обработчик вызывает createTask с waitMs: 0 и возвращает задачу. Сохраните её ID. Успешный ответ означает, что у вас есть задача, но не обязательно решение.

  3. 3.

    Получайте статус через GET

    Вызывайте /captcha/tasks/:id. Продолжайте получать данные, пока статус равен pending или solving; не повторяйте POST для проверки хода выполнения. Остановитесь при ready или failed.

  4. 4.

    Используйте только готовое решение

    Отправляйте токен с возвращёнными userAgent и secChUa, используя тот же настроенный прокси и целевой ресурс. SDK не отправляет его за вас. Готовая задача означает, что решение сгенерировано, а не что целевой ресурс принял запрос вашего приложения.

Обрабатывайте тайм-ауты без создания новой задачи

POST-вызов SDK ограничен 20 секундами через AbortSignal. GET допускает ожидание задачи в течение 15 секунд в пределах 25-секундного ограничения вызова SDK. Ответ GET всё ещё может содержать промежуточный статус; проверяйте его, а не считайте окончание ожидания неудачным решением.

Тайм-аут создания не доказывает, что solvethree отклонил запрос. Если вы получили ID задачи, запросите её. В противном случае повторите создание с тем же ID запроса и неизменными входными данными задачи, чтобы восстановить доступ к существующей задаче. Повторное использование этого ID с другими входными данными вызывает конфликт. Если ID запроса не сохранён, новый POST может создать отдельную задачу.

Express 5 передаёт ошибки отклонённых асинхронных обработчиков промежуточному ПО обработки ошибок. При SolvethreeError пример возвращает HTTP 502, раскрывая только идентификаторы запроса и задачи, но не исходную ошибку, учётные данные или решение. Его резервный ответ HTTP 400 носит общий характер; он не классифицирует точно все ошибки вне SDK, включая ошибки превышения времени выполнения.

Обрабатывайте HTTP-ошибки до чтения данных успешного ответа. Независимо от этого, полученная задача может иметь статус failed: проверьте её errorCode и error, затем прекратите опрос. За неудачные решения средства возвращаются, но повторные запросы с неизменными некорректными входными данными не исправят проблему. Используйте справочник ошибок API для диагностики указанного сбоя.

Запустите первую задачу.

Начните с $5 на балансе рабочего пространства.

Создать рабочее пространство
Используйте сервис решения CAPTCHA в Express · solvethree