はじめに
Webサイトにお問い合わせフォームを公開すると、自動化されたプログラム(ボット)から大量の宣伝やいたずら送信(スパム)が送られてくることがあります。
本記事では、フォームをボットから守りつつ、訪問者にはストレスを与えない Cloudflare Turnstile(ターンスタイル) の基本と、実装時の注意点についてまとめます。
1. ボット対策が必要な理由と従来の課題
ボット対策を行わないと、迷惑メールで大切な連絡を見落としたり、メール配信サービスの送信上限を消費されたりするリスクがあります。代表的な対策の比較は以下の通りです。
| 手法 | 仕組みの概要 | 利用者(人間)の負担と特徴 |
|---|---|---|
| 隠しフィールド(Honeypot) | 画面上では見えない入力欄を置き、すべての欄を機械的に埋めるボットを検知します。 | 人間には負担がありませんが、高度なボットには見破られることがあるため他対策との併用が適しています。 |
| 従来の画像選択 CAPTCHA | 「信号機のタイルをすべて選ぶ」といったパズルで人間か判定します。 | パズルが難しくて離脱につながったり、操作面で負担になったりする課題がありました。 |
| Cloudflare Turnstile | ブラウザの動作環境を裏側で自動確認し、パズルなしで「一時的な認証トークン」を発行します。 | 利用者は何も操作しないかチェックを1回押すだけで完了し、操作の負担を最小限に抑えられます。 |
2. トークンの発行とサーバー側での検証フロー
Turnstileを使う上で大切なのが、「画面にウィジェットを置くだけでは防御にならず、必ずサーバー側で合否を検証する必要がある」 という点です。
sequenceDiagram
participant User as 訪問者 (ブラウザ)
participant Widget as Turnstile ウィジェット
participant Server as 自サイトのAPIサーバー
participant CF as Cloudflare 検証サーバー
User->>Widget: 1. フォーム画面を開く
Widget-->>User: 2. 自動判定し「ワンタイムトークン」を発行
User->>Server: 3. 入力内容と一緒にトークンを送信 (POST)
Server->>CF: 4. トークンと秘密鍵 (Secret Key) を照合
CF-->>Server: 5. 検証結果 (success: true / false) を返却
Server-->>User: 6. 合格したときだけメールを送信して完了表示
- ブラウザ側: ページを開くとTurnstileがブラウザ環境を確認し、一時的な通行証(トークン)を発行します。
- サーバー側: フォーム送信時、自サイトのAPIサーバーは受け取ったトークンを Cloudflare の検証API(
siteverify)へ送り、合格(success: true)したリクエストだけをメール送信へ進めます。
3. 実装してみて学んだ2つのポイント
① 隠しフィールド(Honeypot)と併用して多層的に守る
CSSで非表示にしたダミー欄(Honeypot)も前段に配置しています。単純なボットがダミー欄に入力してきた場合は、外部APIと通信する前に即座にブロックできるため、無駄な通信を減らせます。
② トークンは「1回使い切り」のためエラー時のリセットが必要
Turnstileのトークンは 「1度サーバーで検証すると無効になる(ワンタイムトークン)」 仕様です。通信エラー等で送信が失敗した際、古いトークンのままだと再送信時にエラーになるため、失敗時はリセット処理を呼び出して新しいトークンを再取得させます。
// 送信エラー時にワンタイムトークンを再取得させる処理
if (!response.ok) {
window.turnstile?.reset();
}
まとめ
Cloudflare Turnstile を使うことで、利用者に画像選択の負担をかけずにボット対策を行えます。実装時はサーバー側でのトークン検証と、エラー時のリセット処理を忘れないことが大切です。
このボット対策と多層防御を組み込んだ当サイトの全体像については、制作実績の 型安全性と軽量化を意識した就職活動用ポートフォリオサイト にまとめています。