この記事では、よくある疑問にできるだけお答えしました。まず最初のステップは、どのような保護システムが使われているかを特定することです。そのために、代表的なキャプチャやボット対策システムの一覧を参照できます。ここには、どの仕組みが使われているかを素早く見分けるための画面イメージや主な特徴がまとめられています。
もしサイトで TenDI (Tencent) が使われていることが分かったら、次のステップはその特徴と動作をより詳しく確認することです。同じこの記事の中で、TenDI (Tencent) をサイトに導入するための手順書も確認できるので、あなたのサイト上でどのように機能しているのかをしっかり理解できます。これにより、現在の保護を正しく把握できるだけでなく、今後の運用や保守も計画的に行えるようになります。
CapMonster Cloud API を使った一般的な手順:
type - CustomTask
class - TenDI
websiteURL - キャプチャを解くページのURL。
websiteKey - captchaAppId。例: "websiteKey": "189123456" — あなたのサイトの一意のパラメータ
captchaUrl (metadata内) - キャプチャスクリプトへのリンク。通常はTCaptcha.jsまたはTCaptcha-global.jsで終わります;
websiteURL - キャプチャを解くページのURL;
userAgent (任意) - ブラウザのUser-Agent。Windowsの最新UAのみ送信。
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';
// 自分の値に置き換えてください
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. ページを開く
await page.goto(WEBSITE_URL, { waitUntil: 'networkidle' });
// 2. キャプチャが表示されるのを待つ(例:inputまたはiframe)
await page.waitForSelector('#tendi_response, iframe[src*="tendi"], input[name="tendi_response"]', { timeout: 15000 });
// 必要に応じてページからwebsiteKeyを抽出可能
const WEBSITE_KEY = await page.evaluate(() => {
// 例:sitekeyはdata属性またはグローバル変数にある場合があります
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. TenDIタスクを作成
const tenDIRequest = new TenDIRequest({
websiteURL: page.url(),
websiteKey: WEBSITE_KEY,
});
const balance = await client.getBalance();
console.log("Balance:", balance);
// 4. キャプチャを解く
const solution = await client.Solve(tenDIRequest);
console.log("Solution:", solution);
const { ticket, randstr } = solution.solution.data;
// 5. 解決結果の挿入方法
await page.evaluate(({ ticket, randstr }) => {
// 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;
}
}
// JS callback関数
if (typeof window.onCaptchaSolved === 'function') {
window.onCaptchaSolved(ticket, randstr);
inserted = true;
}
// inputや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);
2つのパラメータを取得:CaptchaAppIdとAppSecretKey。フロントエンドとサーバーで使用します。
クリックでキャプチャが表示され、解決後に結果がコンソールに出力されます。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Captcha Example</title>
// キャプチャJSの読み込みは必須
<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>
// 結果の処理
function callback(res) {
console.log("callback:", res);
if (res.ret === 0) {
// 検証成功
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とrandstrがクリップボードにコピーされました。");
}
}
// キャプチャスクリプト読み込みエラーの処理
function loadErrorCallback() {
const appid = "CaptchaAppId";
const ticket = `trerror_1001_${appid}_1769260299`;
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>
統合の仕組み
ステップ1: キャプチャJSを読み込む
スクリプトは動的に読み込む必要があります:
<script src="https://ca.turing.captcha.qcloud.com/TJNCaptcha-global.js"></script>標準外の方法やキャッシュ化をすると、キャプチャが正しく動作しない場合があります。
ステップ2: TencentCaptchaオブジェクト作成
JS読み込み後、グローバルクラスが出現:
<script src="new TencentCaptcha(domElement, CaptchaAppId, callback, options);"></script>パラメータ:
domElement - チェックボックス/iframeを埋め込むコンテナ
CaptchaAppId - あなたのID
callback - 検証後のアクション
options - 外観設定(任意)
ステップ3: メソッド呼び出し .show()
captcha.show();キャプチャを表示。複数回呼び出し可能。
ステップ4: 結果を処理
Callbackはオブジェクトを受け取る:
{
ret: 0, // 0 -- 成功, 2 -- ユーザーがウィンドウを閉じた
ticket: "...", // サーバーが必要
randstr: "...", // サーバーも必要
errorCode: 1001, // キャプチャが読み込まれなかった場合
errorMessage: "..." // エラーメッセージ
}サーバー側で必ずticketの二次検証を実行してください。
"災害復旧モード"
キャプチャが読み込まれない場合(例: CDNが利用不可)、業務プロセスを妨げないように「緊急チケット」を自動発行できます。
シナリオ:
trerror_<errorcode>_<appid>_<timestamp>AppId暗号化(任意)
最大限の保護が必要な場合、キャプチャに公開AppIdではなく暗号化されたバージョンを渡すことができます:
aidEncrypted = Base64(IV + AES256(AppId & timestamp & ttl))必要なもの:
サーバー側暗号化例(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")サーバー側検証
ステップ1. APIアクセス設定
キー管理パネル(CAM / API Key Management)でSecretIdとSecretKeyを取得。署名付きAPIリクエストに必要。
ステップ2. API DescribeCaptchaResult呼び出し
クライアントがticketとrandstrを返した後、サーバーはリクエストを送信:
パラメータ:
CaptchaType - 9 (固定値)
Ticket - 文字列 — ticket、クライアントから返却
Randstr - 文字列 — randstr、クライアントから返却
CaptchaAppId - あなたのAppId
AppSecretKey - あなたのSecretKey
UserIp - ユーザーIP(推奨)
ステップ3. 応答処理
APIは以下を返す:
CaptchaCode === OKの場合、ユーザーは検証済みとみなされます。そうでない場合は拒否。
例 — Node.jsでのticket検証
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", // 必要な場合、リージョン指定
});
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;
}Tencent CAPTCHAをサイトに接続する詳細情報は公式ドキュメントにあります。
すでにキャプチャや別の保護システムが導入されているサイトを引き継いだものの、コードにはアクセスできない場合でも心配はいりません!どの技術が使われているかを特定するのはそれほど難しくありません。動作が正しいか確認するには、隔離されたテスト環境で認識サービスCapMonster Cloudを利用し、トークン処理の仕組みと検証ロジックが正しく機能しているかをチェックできます。
TenDI (Tencent)の場合も、システムを特定し、その挙動を調べて、保護機能が正しく動いていることを確認すれば十分です。この記事では、TenDI (Tencent)を見分ける方法と、その導入や再設定に関する手順書の見つけ方を紹介しました。これにより、防御を安心して維持し、その動作をしっかりと管理できます。