Integrations

Résoudre les CAPTCHA dans un service Spring Boot 3

Résoudre un CAPTCHA dans un service Spring Boot 3 revient à un enchaînement précis : un bean interne envoie les paramètres du défi à l'API CaptchaAI, attend le token, puis le réinjecte dans la requête qui a déclenché le défi. La vraie difficulté n'est pas de réussir cet appel une fois dans un test, mais de le rendre assez stable pour tourner en continu dans un job planifié ou une chaîne d'intégration continue. Ce guide décrit une intégration propre et observable pour Spring Boot 3 (Java 17+).

Périmètre sûr : Ce guide s'applique exclusivement à vos propres applications, environnements de QA, de préproduction ou de production, ou à des systèmes pour lesquels vous disposez d'une autorisation écrite. Il ne décrit ni l'automatisation de sites tiers, ni le contournement de protections, ni l'évasion d'anti-bot.

Un bean dédié à la résolution

Isolez la logique CAPTCHA dans un seul @Service. Ce composant reçoit les paramètres du défi (sitekey, URL de la page, éventuellement un proxy), appelle CaptchaAI en HTTPS via un RestClient ou un WebClient (Spring Framework 6.1), récupère le token et le renvoie à l'appelant. Une seule responsabilité, une seule surface à tester.

Tracez chaque étape avec un identifiant de tâche unique : lors d'une montée de version, cette trace montre immédiatement si une régression vient de la résolution ou de la réinjection. Le contrat reste le même quelle que soit la famille visée : reCAPTCHA v2, reCAPTCHA v3, Cloudflare Turnstile, GeeTest v3 ou les CAPTCHA image/OCR passent tous par la même boucle envoi/interrogation.

Où placer la clé API dans Spring Boot

La clé CaptchaAI ne vit jamais dans application.properties versionné. Stockez-la dans un coffre (HashiCorp Vault, AWS Secrets Manager, Azure Key Vault) ou un secret CI, montez-la en variable d'environnement au runtime, et exposez-la par @ConfigurationProperties ou @Value("${captchaai.key}") plutôt qu'en constante en dur.

Cette séparation vous permet de faire tourner la clé sans redéployer et de garder des valeurs distinctes entre préproduction et production. Sur OVHcloud ou Scaleway, elle se branche sur le gestionnaire de secrets de la plateforme.

Appeler CaptchaAI depuis votre service

L'exemple ci-dessous montre l'appel côté serveur dans votre propre service. Il envoie une tâche Turnstile et renvoie l'identifiant de tâche ; en Spring, vous transposez la même requête avec WebClient ou RestClient :

import fetch from 'node-fetch';

const API_KEY = process.env.CAPTCHAAI_KEY;

export async function createTurnstileTask(siteKey, pageUrl) {
  const res = await fetch('https://api.captchaai.com/createTask', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      clientKey: API_KEY,
      task: {
        type: 'TurnstileTaskProxyless',
        websiteURL: pageUrl,
        websiteKey: siteKey,
      },
    }),
  });
  const data = await res.json();
  return data.taskId;
}

Pour changer de famille de CAPTCHA, modifiez le type de tâche et gardez la même mécanique : soumettre, puis interroger le résultat. C'est ce qui rend l'intégration portable et peu coûteuse.

Réinjecter le token dans la même session

Le token obtenu doit être appliqué dans la session qui a déclenché le défi : même contexte de navigateur, même client HTTP, même file de cookies. Un token valide appliqué dans une autre session est la cause la plus fréquente de rejet après résolution. Dans un service Spring Boot, conservez donc le token et la soumission du formulaire dans le même WebClient plutôt que de le faire transiter par un composant qui repart d'une session vierge.

Interroger le résultat sans bloquer vos threads

N'immobilisez jamais un thread de servlet pendant deux minutes en attente d'un token. Après l'envoi, attendez 15 secondes, puis interrogez le résultat toutes les 5 secondes avec un plafond ferme de 120 secondes par tâche ; une boucle réactive WebClient ou une méthode @Async libère le pool de requêtes pendant l'attente. Bornez toujours le nombre de tentatives : trois essais avec un backoff exponentiel plafonné absorbent les erreurs transitoires sans masquer un vrai défaut ni consommer votre solde inutilement.

Observabilité avec Micrometer et Actuator

Instrumentez chaque appel CAPTCHA pour obtenir des métriques exploitables : durée d'obtention du token, code retour HTTP, identifiant de tâche et taille de la file d'attente interne. Un Timer Micrometer exposé via Actuator vers Prometheus suffit à alimenter vos tableaux de bord et vos alertes.

Séparez les journaux par environnement et corrélez-les à votre traçage distribué (OpenTelemetry) pour rejouer un scénario à partir d'un identifiant unique. Côté conformité, minimisez les données personnelles écrites dans les logs : un identifiant de tâche et un horodatage suffisent au débogage, et vous restez aligné sur vos obligations RGPD.

Suivez enfin deux indicateurs distincts : la réussite de la résolution et celle du parcours métier en aval. Un token résolu n'est pas encore un formulaire accepté. Visez une médiane sous 25 s pour les CAPTCHA à token et un taux de réussite d'au moins 95 % par famille.

Liste de contrôle avant la mise en production

  • Le périmètre est strictement limité à vos propres applications ou à des sources autorisées.
  • La clé CaptchaAI est stockée dans un secret CI ou un coffre, jamais dans le code source.
  • Les durées d'appel et les codes retour sont tracés pour chaque exécution.
  • L'interrogation du résultat est bornée (15 s d'attente, 5 s d'intervalle, plafond de 120 s).
  • Une stratégie de retry idempotent avec backoff exponentiel couvre les erreurs transitoires.
  • Les tests sont rejouables et reproductibles depuis votre intégration continue.

Dépannage

Problème Cause probable Correctif
ERROR_WRONG_USER_KEY Clé copiée avec un espace parasite ou mauvais compte. Recopiez la clé depuis le tableau de bord et stockez-la en secret CI.
ERROR_ZERO_BALANCE Solde inférieur au minimum par tâche. Rechargez le solde et ajoutez une alerte de seuil dans votre tableau de bord.
ERROR_PAGEURL / ERROR_BAD_PARAMETERS Paramètre requis manquant ou mal formé. Revalidez l'URL de la page et le sitekey contre le HTML réel de la page.
Token refusé après résolution Token appliqué dans une session différente de celle du défi. Gardez la résolution et l'envoi du formulaire dans le même client HTTP.

FAQ

Faut-il un thread dédié pour chaque appel CAPTCHA ?

Non. CaptchaAI facture par thread concurrent, avec des résolutions illimitées par thread : un thread correspond à un CAPTCHA en cours et se libère dès la résolution terminée. Le plan BASIC ($15/mois, 5 threads) autorise donc cinq résolutions simultanées. Dimensionnez vos threads sur votre débit réel.

Comment interroger le résultat sans bloquer un thread Spring ?

Utilisez une boucle réactive WebClient ou une méthode @Async : le thread de requête est rendu au pool pendant l'attente, et un plafond de 120 secondes par tâche évite qu'un défi bloqué n'immobilise vos ressources.

Où stocker la clé API CaptchaAI dans un projet Spring Boot ?

Dans un coffre de secrets ou une variable d'environnement injectée au runtime, jamais dans un application.properties versionné. Exposez-la par @Value pour la faire tourner sans toucher au code.

Le token Turnstile est refusé alors qu'il est bien résolu, pourquoi ?

Presque toujours parce qu'il est appliqué dans une autre session que celle du défi. Conservez le même client HTTP et la même file de cookies entre la résolution et l'envoi du formulaire.

Guides connexes

Fiabilisez vos workflows CAPTCHA avec une approche méthodique et reproductible. – Obtenez votre clé CaptchaAI.

Les commentaires sont désactivés pour cet article.