Skip to content

非公式本サイトは非公式の日本語ドキュメントであり、Cloudflare 公式サイトではありません。最新情報はdevelopers.cloudflare.comをご確認ください。

Turnstile、WAF、Bot Management を連携する

最終更新 Markdown で表示Agent セットアップ

このチュートリアルでは、既存の認証システムに Cloudflare Turnstile、Web Application Firewall(WAF)Bot Management を組み込みます。自動化攻撃や悪意のあるログイン試行など、さまざまな脅威に対する多層防御を構築できます。

概要

WAF と Bot Management を使うには、サイトの DNS を Cloudflare 経由にする必要があります。一方、Turnstile は Cloudflare のネットワーク上にないサイトを含め、どのサイトでも単独で使えます。このチュートリアルでは 3 つの製品すべての導入を扱います。サイトが Cloudflare のネットワーク上にない場合は、Turnstile だけに絞ってもかまいません。

WAF、Bot Management、Turnstile は、アプリケーションの異なる層で動作するため、組み合わせて使えます。

  • WAF はネットワークシグナルに基づいて悪意のあるトラフィックをフィルタします。
  • Bot Management はリクエストを分析し、自動化された脅威を特定して緩和します。
  • Turnstile はクライアント側とブラウザーのシグナルを調べ、人間のユーザーとボットを区別します。

サーバー側(WAF と Bot Management)とクライアント側(Turnstile)の対策を組み合わせると、攻撃者が回避しにくい多層防御になります。

始める前に

  • WAF と Bot Management を使う場合は、それらにアクセスできる Cloudflare アカウントが必要です。
  • 認証を処理する、既存の JavaScript / TypeScript ベースのルートがあること。

このチュートリアルでは、Turnstile をアプリケーションへ組み込む例として、プレーン HTML の簡単なログインフォームを使います。バックエンドでは、TypeScript で書いたスタブの認証ルートがログインリクエストを処理します。言語は任意に差し替えられます。使っている言語やフレームワークが Turnstile の API へ外部 HTTP リクエストを送れるなら、Turnstile を組み込めます。

WAF と Bot Management を設定する

サイトが Cloudflare のネットワーク上にあり、Enterprise プランに加入している場合は、WAF と Bot Management を設定する必要があります。

ボットの可能性があるトラフィックにチャレンジを出す

  1. Cloudflare ダッシュボードで、WAF ページを開きます。

    WAF を開く ↗
  2. Edit expression を選び、新しいカスタム WAF ルールを作成します。

    • フィールド: 「Bot Score」
    • 演算子: 「less than or equal to」
    • 値: 「30」
    • アクション: 「Managed Challenge」

この設定は、ボットスコアが低いリクエストにチャレンジを出します。ネットワークシグナルで潜在的な脅威を、アプリケーションに届く前に特定します。スコアのしきい値は、用途に合わせて変更できます。

Cloudflare Turnstile を設定する

Turnstile は、サイトが Cloudflare のネットワーク上にあるかどうかに関係なく使えます。

  1. Cloudflare ダッシュボードで、Turnstile ページを開きます。

    Turnstile を開く ↗
  2. Add widget を選び、必要な情報を入力します。

  3. Turnstile の設定にドメインを追加します。

  4. Create を選びます。

Turnstile はブラウザーとクライアント側のシグナルを分析し、WAF と Bot Management によるサーバー側の検査を補完します。

サイトが Cloudflare 上にある場合は、Turnstile の設定で既存の クリアランス Cookie を使うオプションを有効にできます。この連携により、Turnstile はユーザーにチャレンジを出すかどうかを判断する材料として、クリアランス Cookie を使えます。任意ですが、すでに WAF と Bot Management を使っている場合は推奨します。

アプリケーションに Turnstile を組み込む

Turnstile の実装には、Turnstile ウィジェットとサーバー側の検証ロジックの 2 つが必要です。

ログインフォームに Turnstile ウィジェットを追加する

既存のログインフォームに Turnstile ウィジェットを追加します。

<form id="login-form">
	<input type="text" id="username" placeholder="Username" required />
	<input type="password" id="password" placeholder="Password" autocomplete="off" required />
	<div class="cf-turnstile" data-sitekey="<YOUR-SITE-KEY>"></div>
	<button type="submit">Log in</button>
</form>

<script
	src="https://challenges.cloudflare.com/turnstile/v0/api.js"
	async
	defer
></script>

<YOUR-SITE-KEY> を、実際の Turnstile サイトキーに置き換えます。

ログインリクエストを処理する

既存の認証ルートに、Turnstile の検証を追加します。

async function validateTurnstileToken(
	ip: string,
	token: string,
	secret: string,
): Promise<boolean> {
	const response = await fetch(
		"https://challenges.cloudflare.com/turnstile/v0/siteverify",
		{
			method: "POST",
			headers: { "Content-Type": "application/json" },
			body: JSON.stringify({ ip, secret, response: token }),
		},
	);

	const outcome = await response.json();
	return outcome.success;
}

// Assume that this is a TypeScript route handler.
// You may replace this with a different implementation,
// based on your language or framework
export async function onRequestPost(context) {
	const { request, env } = context;
	const { username, password, token } = await request.json();

	// Validate Turnstile token
	const secretKey = env.TURNSTILE_SECRET_KEY;
	const ip = request.headers.get("CF-Connecting-IP");
	const turnstileValid = await validateTurnstileToken(ip, token, secretKey);
	if (!turnstileValid) {
		// Return back to the login page with an error message
		return Response.redirect("/login", 302, {
			headers: {
				Location: "/login?error=invalid-turnstile-token",
			},
		});
	}

	// Perform your existing authentication logic here
	const isValidLogin = await checkCredentials(username, password);

	if (isValidLogin) {
		return new Response(JSON.stringify({ message: "Login successful" }), {
			status: 200,
			headers: { "Content-Type": "application/json" },
		});
	} else {
		return new Response(JSON.stringify({ error: "Invalid credentials" }), {
			status: 401,
			headers: { "Content-Type": "application/json" },
		});
	}
}

async function checkCredentials(
	username: string,
	password: string,
): Promise<boolean> {
	// Your existing credential checking logic
}

この構成では、ログイン処理の前にサーバー側で Turnstile トークンを検証します。クライアント側シグナルに基づく防御が追加されます。

テスト

デプロイ後は、連携をテストしてください。ボットスコアが低いため、チャレンジは出ないことが多いです。必要に応じて追加ルールを作り、チャレンジページへ強制的にリダイレクトできます。次のような方法があります。

  1. 自分の IP アドレスを常にチャレンジページへ転送する WAF ルールを追加します。
  2. ?challenge=true などのクエリパラメーターの有無を確認する WAF ルールを追加します。

ベストプラクティス

  1. 資格情報を確認する前に、必ずサーバー側で Turnstile トークンを検証します。
  2. Turnstile のシークレットキーなどの機密情報は、環境変数に保存します。
  3. 適切なエラー処理とログを実装し、セキュリティ上の問題を監視します。

Turnstile を WAF と Bot Management と組み合わせると、ネットワーク層でアプリケーションを守りつつ、クライアント側シグナルでもう一層の保護を追加できます。悪意のある攻撃者がログインシステムへの自動化攻撃を仕掛けることが、かなり難しくなります。

関連リソース

Turnstile をカスタマイズする場合は、次のリソースを参照してください。

  • クライアント側レンダリング。アプリケーションの要件とユーザー体験に合わせて、Turnstile を UI のどこで、いつ描画するかをカスタマイズできます。
  • サーバー側検証。Turnstile の API の動き、リクエストパラメーター、エラーコードを含む各種レスポンスの扱いを確認できます。
  • Turnstile Analytics。Cloudflare ダッシュボードで Turnstile の分析を確認できます。発行されたチャレンジ数や、チャレンジ解決率(CSR) などの指標が含まれます。

役に立ちましたか?