Cloudflare Turnstileで問い合わせフォームのスパムを防ぐ
企業サイトの問い合わせフォームには、人間ではなくボットが自動送信している営業目的・詐欺目的のメールが一定数届きます。1件1件は大きな被害ではなくても、確認・削除の手間が積み重なると業務を圧迫しますし、まれに巧妙な内容が本物の問い合わせに紛れて見落とされるリスクもあります。この対策として広く使われてきた「画像の中の信号機を選んでください」型のCAPTCHAに代わり、近年はCloudflare Turnstileのような、ユーザーにほとんど負担をかけないボット対策が主流になりつつあります。
従来のCAPTCHAが抱える問題
reCAPTCHAをはじめとする従来型のCAPTCHA(そもそもCAPTCHAはどう機能するのか)には、いくつかの課題が指摘されています。
- ユーザー体験の悪化:画像選択やチェックボックスのクリックといった追加操作が、フォーム離脱の一因になる
- Googleへの依存とプライバシー:reCAPTCHAはGoogleのスクリプトを読み込み、ユーザーの行動データがGoogleに送信される。BtoBサイトでは取引先の情報保護方針と相性が悪い場合がある
- 表示の重さ:ウィジェットの読み込みがページ表示速度に影響することがある
Cloudflare Turnstileは、これらの課題に対して「ユーザーに極力何もさせない」方向でアプローチしたサービスです。
Cloudflare Turnstileの仕組み
Turnstileは、ブラウザの挙動・実行環境・過去のトラフィック傾向などをCloudflare側で解析し、多くの場合ユーザーに何も操作させずに「人間らしいアクセスかどうか」を判定します。判定が難しいケースでのみ、簡易なチェックボックス操作を挟みます。フォーム送信の裏側では、次の3段階で検証が行われます。
- フロントエンド:ページにTurnstileのウィジェットを埋め込むと、送信時に検証用の「トークン」が発行される
- フォーム送信:発行されたトークンを、フォームの他の入力内容と一緒にサーバーへ送信する
- サーバーサイド検証:受け取ったトークンをCloudflareの検証API(
siteverify)に送り、正当なアクセスかどうかの判定結果を受け取る
この3段階目のサーバーサイド検証を省略すると、フロントエンドのウィジェットだけを回避する形でスパムを送られてしまうため、必ずセットで実装する必要があります。
実装例
フロントエンド:ウィジェットの埋め込み
<script src="https://challenges.cloudflare.com/turnstile/v0/api.js" async defer></script>
<form action="/api/contact" method="POST">
<!-- 通常の入力項目 -->
<div class="cf-turnstile" data-sitekey="サイトキー"></div>
<button type="submit">送信</button>
</form>data-sitekeyにはCloudflareダッシュボードで取得した公開用の「サイトキー」を指定します。送信時、cf-turnstile-responseという名前の隠しフィールドが自動生成され、検証用トークンがそこに入ります。
サーバーサイド:トークンの検証(PHP例)
<?php
$token = $_POST['cf-turnstile-response'] ?? '';
$secretKey = 'シークレットキー'; // git管理外で保持する
$response = file_get_contents(
'https://challenges.cloudflare.com/turnstile/v0/siteverify',
false,
stream_context_create([
'http' => [
'method' => 'POST',
'header' => 'Content-Type: application/x-www-form-urlencoded',
'content' => http_build_query([
'secret' => $secretKey,
'response' => $token,
'remoteip' => $_SERVER['REMOTE_ADDR'],
]),
],
])
);
$result = json_decode($response, true);
if (empty($result['success'])) {
// 検証失敗:ボットの疑いがあるため送信を拒否
http_response_code(400);
exit('検証に失敗しました。');
}
// 検証成功:通常の送信処理へsecret(シークレットキー)はサーバー側だけが保持する値のため、フロントエンドのコードには一切含めず、リポジトリにコミットしない設定ファイルや環境変数として管理します。
Cloudflareでホスティングしていないサイトでも使える
Turnstileは「ボット判定APIを叩いて結果を受け取る」だけの独立したサービスなので、サイトの実体がCloudflare Pages上になくても、Apache・NginxなどのFTP/レンタルサーバーで動いている一般的なPHPサイトでも問題なく組み込めます。DNSをCloudflare経由にする必要もありません。ドメインをCloudflareダッシュボードに登録してサイトキー・シークレットキーを発行すれば、あとはHTMLとサーバーサイドのAPI呼び出しだけで完結します。
導入効果の目安
問い合わせフォームに1日あたり10件を超える営業目的の自動送信メールが届いていたサイトで、Turnstileを導入した結果、フォーム経由のスパムがほぼ0件になった、というケースも珍しくありません。CAPTCHAと違って追加の操作をほとんど要求しないため、正規の問い合わせを妨げずにスパムだけを減らせるのが特徴です。導入直後の数日は、検証失敗によって正規の問い合わせまで弾いていないか(サーバー側のログやエラー発生率)を確認しておくと安心です。
まとめ
Cloudflare TurnstileはCAPTCHAが抱えていたユーザー体験・プライバシーの課題を解消しつつ、フロントエンドのウィジェット埋め込みとサーバーサイドのsiteverify検証という2ステップで実装できる手軽さが強みです。Cloudflareでホスティングしていないサイトでも単体で導入できるため、問い合わせフォーム経由のスパムに悩んでいる場合、コストをかけずに試せる対策の一つです。