Dans cet article, nous avons essayé de répondre à toutes les questions essentielles. Pour commencer à résoudre le problème, il faut d’abord déterminer quel système de protection est utilisé. Pour cela, vous pouvez consulter la liste des captchas et systèmes de protection antibot les plus populaires, qui présente des exemples visuels et des caractéristiques clés permettant d’identifier rapidement avec quoi vous avez affaire.
Si vous constatez que votre site utilise TenDI (Tencent), l’étape suivante consiste à étudier plus en détail ses propriétés et son fonctionnement. Dans cet article, vous pouvez également consulter le guide d’intégration de TenDI (Tencent) afin de comprendre pleinement la façon dont il fonctionne sur votre site. Cela vous permettra non seulement de mieux connaître la protection en place, mais aussi de planifier correctement sa maintenance.
Travailler avec CapMonster Cloud via l’API comprend généralement les étapes suivantes :
type - CustomTask
class - TenDI
websiteURL - l'adresse de la page où le captcha est résolu.
websiteKey - captchaAppId. Par exemple, "websiteKey": "189123456" — un paramètre unique pour votre site web.
captchaUrl (dans metadata) - lien vers le script du captcha. Se termine généralement par TCaptcha.js ou TCaptcha-global.js;
websiteURL - l'adresse de la page où le captcha est résolu;
userAgent (optionnel) - User-Agent du navigateur. Fournir uniquement un UA réel et à jour depuis Windows.
https://api.capmonster.cloud/createTask
{
"clientKey": "API_KEY",
"task": {
"type": "CustomTask",
"class": "TenDI",
"websiteURL": "https://example.com",
"websiteKey": "189123456",
"userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/143.0.0.0 Safari/537.36",
"metadata": {
"captchaUrl": "https://global.captcha.example.com/TCaptcha-global.js"
}
}
}
{
"errorId":0,
"taskId":407533072
}https://api.capmonster.cloud/getTaskResult{
"clientKey":"API_KEY",
"taskId": 407533072
}
{
"errorId":0,
"status":"ready",
"solution": {
"data": {
"randstr": "@EcL",
"ticket": "tr03lHUhdnuW3neJZu.....7LrIbs*"
},
"headers": {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/143.0.0.0 Safari/537.36"
}
}
}
// npx playwright install chromium
import { chromium } from 'playwright';
import { CapMonsterCloudClientFactory, ClientOptions, TenDIRequest } from '@zennolab_com/capmonstercloud-client';
// Remplacez par vos propres valeurs
const API_KEY = "YOUR_API_KEY";
const WEBSITE_URL = "https://example.com";
async function solveTenDIOnPage() {
const browser = await chromium.launch({ headless: false });
const context = await browser.newContext();
const page = await context.newPage();
// 1. Ouvrir la page
await page.goto(WEBSITE_URL, { waitUntil: 'networkidle' });
// 2. Attendre l'apparition du captcha (ex : input ou iframe)
await page.waitForSelector('#tendi_response, iframe[src*="tendi"], input[name="tendi_response"]', { timeout: 15000 });
// Si nécessaire, le websiteKey peut être extrait directement de la page
const WEBSITE_KEY = await page.evaluate(() => {
// Exemple : le sitekey peut se trouver dans un attribut data ou une variable globale
const el = document.querySelector('#tendi_response') || document.querySelector('div[data-sitekey]');
return el?.getAttribute('data-sitekey') || window.TenDI_siteKey || "183268248";
});
console.log("Website key detected:", WEBSITE_KEY);
const client = CapMonsterCloudClientFactory.Create(
new ClientOptions({ clientKey: API_KEY })
);
// 3. Créer une tâche TenDI
const tenDIRequest = new TenDIRequest({
websiteURL: page.url(),
websiteKey: WEBSITE_KEY,
});
const balance = await client.getBalance();
console.log("Balance:", balance);
// 4. Résoudre le captcha
const solution = await client.Solve(tenDIRequest);
console.log("Solution:", solution);
const { ticket, randstr } = solution.solution.data;
// 5. Moyens d'injecter le résultat
await page.evaluate(({ ticket, randstr }) => {
// Injection dans un champ input
const inputSelectors = ['#tendi_response', 'input[name="tendi_response"]', 'input[type="hidden"]'];
let inserted = false;
for (const sel of inputSelectors) {
const input = document.querySelector(sel);
if (input) {
input.value = ticket;
input.dispatchEvent(new Event('input', { bubbles: true }));
const form = input.closest('form');
if (form) form.submit();
inserted = true;
break;
}
}
// Fonction callback JS
if (typeof window.onCaptchaSolved === 'function') {
window.onCaptchaSolved(ticket, randstr);
inserted = true;
}
// Si aucun input et aucun callback
if (!inserted) {
window._tenDITicket = ticket;
window._tenDIRandStr = randstr;
console.log("Ticket and randstr saved to window._tenDITicket and window._tenDIRandStr");
}
}, { ticket, randstr });
await page.waitForTimeout(5000);
await browser.close();
}
solveTenDIOnPage().catch(console.error);
Vous recevrez deux paramètres : CaptchaAppId et AppSecretKey. Ils sont utilisés côté frontend et serveur.
Au clic, le captcha apparaît et après résolution, le résultat est affiché dans la console.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Captcha Example</title>
// Chargement obligatoire du JavaScript du captcha
<script src="https://ca.turing.captcha.qcloud.com/TJNCaptcha-global.js"></script>
</head>
<body>
<div id="cap_iframe"></div>
<button id="CaptchaId">Verification</button>
<script>
// Traitement du résultat
function callback(res) {
console.log("callback:", res);
if (res.ret === 0) {
// Vérification réussie
const text = `[randstr] ${res.randstr} | [ticket] ${res.ticket}`;
const input = document.createElement("input");
input.value = text;
document.body.appendChild(input);
input.select();
document.execCommand("Copy");
document.body.removeChild(input);
alert("Ticket et randstr copiés dans le presse-papiers.");
}
}
// Gestion des erreurs lors du chargement du script captcha
function loadErrorCallback() {
const appid = "CaptchaAppId";
const ticket = `trerror_1001_${appid}_1769260364`;
callback({
ret: 0,
randstr: "@" + Math.random().toString(36).slice(2),
ticket,
errorCode: 1001,
errorMessage: "jsload_error",
});
}
window.onload = function () {
document.getElementById("CaptchaId").onclick = function () {
try {
const captcha = new TencentCaptcha(
document.getElementById("cap_iframe"),
"Your CaptchaAppId",
callback,
{}
);
captcha.show();
} catch (e) {
loadErrorCallback();
}
};
};
</script>
</body>
</html>
Comment fonctionne l'intégration
Étape 1 : Charger le JavaScript du captcha
Le script doit être chargé dynamiquement :
<script src="https://ca.turing.captcha.qcloud.com/TJNCaptcha-global.js"></script>Si le script est chargé de manière non standard ou mis en cache, le captcha peut mal fonctionner.
Étape 2 : Créer un objet TencentCaptcha
Après le chargement du JS, une classe globale devient disponible :
<script src="new TencentCaptcha(domElement, CaptchaAppId, callback, options);"></script>Paramètres :
domElement - Conteneur où le checkbox/iframe est intégré
CaptchaAppId - Votre ID
callback - Action après vérification
options - Paramètres visuels (optionnel)
Étape 3 : Appeler la méthode .show()
captcha.show();Affiche le captcha. Peut être appelé plusieurs fois.
Étape 4 : Traiter le résultat
Le callback reçoit un objet :
{
ret: 0, // 0 -- succès, 2 -- l'utilisateur a fermé la fenêtre
ticket: "...", // requis par le serveur
randstr: "...", // également requis par le serveur
errorCode: 1001, // si le captcha n'a pas chargé
errorMessage: "..." // message d'erreur
}Sur le serveur, une vérification secondaire du ticket est obligatoire.
Mode "Disaster Recovery"
Si le captcha ne charge pas (ex : CDN indisponible), un ticket d'urgence peut être généré automatiquement pour ne pas interrompre le processus métier.
Scénario :
trerror_<errorcode>_<appid>_<timestamp>Chiffrement de l'AppId (optionnel)
Pour une protection maximale, vous pouvez transmettre une version chiffrée de l'AppId au captcha au lieu de la version ouverte :
aidEncrypted = Base64(IV + AES256(AppId & timestamp & ttl))Nécessaire :
Exemple de chiffrement côté serveur (Python)
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad
import base64
def encrypt(plaintext, key, iv):
cipher = AES.new(key, AES.MODE_CBC, iv)
ciphertext = cipher.encrypt(pad(plaintext.encode(), AES.block_size))
return base64.b64encode(iv + ciphertext).decode("utf-8")Validation côté serveur
Étape 1. Configurer l'accès à l'API
Dans le panneau de gestion des clés (CAM / API Key Management), obtenez SecretId et SecretKey pour l'API. Ces clés sont nécessaires pour les requêtes signées.
Étape 2. Appeler l'API DescribeCaptchaResult
Après que le client a renvoyé ticket et randstr, le serveur doit envoyer la requête suivante :
Paramètres :
CaptchaType - 9 (valeur fixe)
Ticket - chaîne — ticket renvoyé par le client
Randstr - chaîne — randstr renvoyé par le client
CaptchaAppId - votre AppId
AppSecretKey - votre clé secrète
UserIp - IP de l'utilisateur (recommandé)
Étape 3. Traiter la réponse
L'API renvoie :
Si CaptchaCode === OK, l'utilisateur est considéré comme vérifié. Sinon, rejeter.
Exemple — vérification du ticket en Node.js
import { v20190722 as captcha } from "@tencentcloud/tencentcloud-sdk-nodejs";
const client = new captcha.Client({
credential: {
secretId: "YOUR_SECRET_ID",
secretKey: "YOUR_SECRET_KEY"
},
region: "ap-project", // région, si nécessaire
});
async function verifyCaptcha(ticket, randstr, userIp) {
const params = {
CaptchaType: 9,
Ticket: ticket,
Randstr: randstr,
CaptchaAppId: YOUR_APP_ID,
AppSecretKey: "YOUR_APP_SECRET_KEY",
UserIp: userIp
};
const resp = await client.DescribeCaptchaResult(params);
const code = resp.Response.CaptchaCode;
return code === 0;
}Vous pouvez trouver plus d'informations sur l'intégration de Tencent CAPTCHA sur votre site dans la documentation officielle.
Si vous avez récupéré un site avec un captcha ou un autre système de protection déjà installé, mais sans accès au code, pas de panique ! Il est assez simple d’identifier quelle technologie est utilisée. Pour vérifier que tout fonctionne correctement, vous pouvez utiliser le service de reconnaissance CapMonster Cloud dans un environnement de test isolé, afin de vous assurer que le mécanisme de traitement des jetons et la logique de vérification fonctionnent correctement.
Dans le cas de TenDI (Tencent), il suffit d’identifier le système, d’étudier son comportement et de vérifier que la protection fonctionne correctement. Dans cet article, nous avons montré comment reconnaître TenDI (Tencent) et où trouver les instructions pour son intégration ou sa reconfiguration, afin de maintenir la protection en toute confiance et de garder son fonctionnement sous contrôle.