Llama a la API de CAPTCHA desde Cloudflare Workers

Por solvethree4 min de lectura

Usa un Worker para llamar a la API de tareas de solvethree con fetch en el servidor. Guarda la clave de API del espacio de trabajo en un enlace de secreto, fija los parámetros de destino en el Worker y devuelve las respuestas de las tareas únicamente al cliente autorizado de tu aplicación.

En esta página

Configura el destino y los secretos

Primero, activa en la consola el perfil del sitio de destino para tu espacio de trabajo. Enviar un nombre de host y una acción no crea un perfil. Consulta la configuración del perfil del sitio si aún no has cumplido este requisito previo.

  • SOLVETHREE_API_KEY: la clave de API de tu espacio de trabajo, almacenada como secreto del Worker.
  • INTEGRATION_KEY: un secreto independiente que el cliente de tu aplicación debe enviar en x-integration-key.
  • SOLVETHREE_PROXY: la URL del proxy utilizado para la resolución. Guárdala como secreto si contiene credenciales.
  • CAPTCHA_SITE: el nombre de host de destino, no una URL completa.

El ejemplo fija la acción en login y proporciona un proxy. Cambia esos parámetros del despliegue para adaptarlos a tu integración; no aceptes parámetros de destino arbitrarios de los clientes. Si se omite recaptchaType, la API usa reCAPTCHA Enterprise v3 de forma predeterminada.

Usa la clave de integración entre un cliente de aplicación de confianza y el Worker, no en código de navegador distribuido públicamente. Es una credencial compartida, no una autorización de tareas por usuario.

Crea y recupera tareas

Worker · llamadas REST autenticadas de creación y recuperación
export default {
  async fetch(request, env) {
    if (!env.INTEGRATION_KEY || request.headers.get('x-integration-key') !== env.INTEGRATION_KEY) {
      return new Response('Unauthorized', { status: 401 });
    }
    const url = new URL(request.url);
    const headers = { Authorization: `Bearer ${env.SOLVETHREE_API_KEY}`, 'Content-Type': 'application/json' };
    let response;
    if (request.method === 'POST') {
      const requestId = request.headers.get('x-request-id');
      if (!requestId || !/^[A-Za-z0-9_-]{1,64}$/.test(requestId)) return new Response('Provide X-Request-ID', { status: 400 });
      response = await fetch('https://api.solvethree.com/v1/tasks?waitMs=0', {
        method: 'POST', headers, redirect: 'error', signal: AbortSignal.timeout(20000),
        body: JSON.stringify({ site: env.CAPTCHA_SITE, action: 'login', proxy: env.SOLVETHREE_PROXY, requestId }),
      });
    } else if (request.method === 'GET') {
      const id = url.searchParams.get('id');
      if (!id || !/^[A-Za-z0-9_-]{1,128}$/.test(id)) return new Response('Provide a valid id', { status: 400 });
      response = await fetch(`https://api.solvethree.com/v1/tasks/${encodeURIComponent(id)}?waitMs=15000`, {
        headers, redirect: 'error', signal: AbortSignal.timeout(25000),
      });
    } else return new Response('Use POST or GET', { status: 405 });
    if (!response.ok) return Response.json({ error: 'Solver API request failed', status: response.status }, { status: response.status });
    return Response.json(await response.json(), { headers: { 'Cache-Control': 'no-store' } });
  },
};
// Store keys in Worker secret bindings. The task proxy field does not add a
// generic HTTP proxy option to Workers fetch; another client must submit through it.
  1. 1.

    Crea una tarea

    Envía una solicitud POST al Worker con x-integration-key y x-request-id. Elige un ID de solicitud que contenga entre 1 y 64 letras ASCII, números, guiones bajos o guiones. El Worker construye el cuerpo de la tarea a partir del destino y el proxy configurados; no usa un cuerpo proporcionado por el cliente.

  2. 2.

    Conserva el ID de la tarea

    El Worker devuelve la respuesta JSON del servicio de resolución. Guarda el ID de tarea devuelto y conserva el ID de solicitud utilizado para crearla.

  3. 3.

    Recupera el resultado

    Envía una solicitud GET al Worker con el ID de tarea en el parámetro de consulta id y el mismo encabezado de clave de integración. El manejador valida la sintaxis del ID y recupera esa tarea de solvethree.

Ambas solicitudes al servicio se autentican con la clave del espacio de trabajo. El manejador reenvía los códigos de estado HTTP que no indican éxito con un cuerpo de error genérico y marca las respuestas JSON correctas con Cache-Control: no-store. No comprueba la propiedad de la tarea más allá de la clave de integración compartida; añade esa autorización antes de permitir que distintos usuarios recuperen tareas.

Gestiona los tiempos de espera agotados sin crear otra tarea

La creación usa waitMs=0 con un tiempo de espera de fetch de 20 segundos. La recuperación usa waitMs=15000 con un tiempo de espera de fetch de 25 segundos. Estos límites acotan las llamadas HTTP individuales, no la duración total de la tarea.

Si se agota el tiempo de espera de creación antes de recibir un ID de tarea, repite la misma solicitud de tarea con el mismo ID de solicitud. Así se recupera la tarea existente si llegó a crearse. No generes un ID nuevo solo porque haya fallado la conexión: es posible que la primera solicitud ya haya llegado a solvethree. Reutilizar un ID con parámetros modificados produce un conflicto.

El ejemplo no captura las excepciones de fetch, incluidos los tiempos de espera agotados. Añade gestión de excepciones si tu cliente necesita una respuesta de error estructurada, pero conserva el ID de solicitud para la recuperación.

  • pending o solving: vuelve a recuperar la misma tarea, respetando un plazo global en tu cliente.
  • ready: la solución está disponible; deja de consultar y pásala al cliente de envío.
  • failed: deja de consultar e inspecciona errorCode y error. Corrige el problema indicado antes de crear otra tarea.

Un error HTTP y una tarea con estado failed son fallos distintos. El manejador comprueba primero el estado HTTP; el cliente debe inspeccionar también el estado de la tarea en una respuesta correcta. Para el diagnóstico, consulta errores de la API de CAPTCHA.

Envía mediante un cliente que pueda usar el proxy

El ejemplo de Worker solo llama a solvethree. El campo proxy de la tarea indica al servicio de resolución qué proxy debe usar; no cambia el enrutamiento de red del Worker. fetch de Workers no tiene una opción genérica de URL de proxy.

Envía la solución lista a un cliente que pueda enviarla al destino previsto a través del mismo proxy. Usa los valores userAgent y secChUa devueltos en la solución en lugar de encabezados de navegador ajenos. Una tarea lista significa que solvethree ha generado una solución; su aceptación depende de la solicitud posterior al destino.

Ejecuta tu primera tarea.

Empieza con $5 de crédito en tu espacio de trabajo.

Crear un espacio de trabajo
Llama a la API de CAPTCHA desde Cloudflare Workers · solvethree