HTML/CSSphp

【脱reCAPTCHA】Cloudflare Turnstileを自作PHPフォームに実装する完全ガイド

1 Views

お問い合わせフォームへのスパム対策として長らくGoogleのreCAPTCHAが主流でしたが、ユーザーに画像選択を強いる動作はUX(ユーザー体験)を損なう要因となっていました。 そこで注目されているのが「Cloudflare Turnstile」です。これはユーザーの操作なし(あるいはワンクリック)で人間かボットかを判別できる、プライバシー重視のスマートなソリューションです。

今回は、プラグインを使わず、自前のHTMLフォームとPHPでこのTurnstileを実装する手順を解説します。なお、WordPressのContact Form 7プラグイン等は、Cloudflare Turnstileのサイトキーとシークレットキーがあれば、簡単に設定可能です。

1. Cloudflareへの登録とキーの発行

まず、Cloudflare側で設定を行い、認証に必要な2つのキー(サイトキー・シークレットキー)を取得します。はじめてCloudflareを利用する場合は、ユーザー登録が必要です。

  1. Cloudflareダッシュボードへアクセス Cloudflareのアカウントにログインし、左サイドバーのメニューから [Turnstile] を選択します。
  2. サイトの追加 画面にある [サイトを追加] ボタンをクリックします。
  3. 設定項目の入力
    • サイト名: 管理しやすい名前を入力(例: ブログお問い合わせフォーム)
    • ドメイン: 設置するサイトのドメインを入力
    • ウィジェットモード: 基本的には 「管理(Managed)」 を選択します。これを選ぶと、Cloudflareが自動的に最適な認証方法(非表示、チェックボックス等)を判断してくれます。
  4. キーの取得 作成が完了すると、以下の2つのキーが表示されます。必ず控えておいてください。
    • サイトキー (Site Key): 公開鍵。HTML側に埋め込みます。
    • シークレットキー (Secret Key): 秘密鍵。PHP(サーバー)側で使用します。

2. HTMLフォームへの実装(クライアントサイド)

フォームを表示するHTMLファイル(WordPressなら固定ページのテンプレートなど)に、JavaScriptと専用のdivタグを設置します。

実装のポイント

  • <head>内(またはbodyの閉じタグ直前)にスクリプトを読み込む。
  • フォーム内の認証を表示させたい場所に div タグを配置し、data-sitekey に取得したサイトキーを記述する。

コード例 (index.html / contact.php)

HTML

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>お問い合わせ</title>
    <script src="https://challenges.cloudflare.com/turnstile/v0/api.js" async defer></script>
</head>
<body>

    <h1>お問い合わせフォーム</h1>

    <form action="send.php" method="POST">
        <div>
            <label>お名前:<input type="text" name="your_name" required></label>
        </div>
        <div>
            <label>メール:<input type="email" name="your_email" required></label>
        </div>
        
        <div class="cf-turnstile" data-sitekey="ここにサイトキーを入力"></div>
        
        <br>
        <button type="submit">送信する</button>
    </form>

</body>
</html>

3. PHPによる検証とメール送信(サーバーサイド)

フォームが送信された際、サーバー側(PHP)で「その認証が正当なものか」をCloudflareに問い合わせる必要があります。

処理の流れ

  1. POSTデータに含まれる cf-turnstile-response を取得する。
  2. そのトークンとシークレットキーをセットにして、Cloudflareの検証APIへ送信する。
  3. 返ってきた結果が success: true ならメール送信処理へ進む。

コード例 (send.php)

PHP

<?php
// Cloudflareから取得したシークレットキー
define('TURNSTILE_SECRET_KEY', 'ここにシークレットキーを入力');

// フォームから送信されたトークンを取得
$token = $_POST['cf-turnstile-response'] ?? '';
$remoteIp = $_SERVER['REMOTE_ADDR'];

// 1. Cloudflareの検証APIに問い合わせる関数
function verifyTurnstile($token, $ip) {
    $url = "https://challenges.cloudflare.com/turnstile/v0/siteverify";
    
    $data = [
        'secret'   => TURNSTILE_SECRET_KEY,
        'response' => $token,
        'remoteip' => $ip,
    ];

    $options = [
        'http' => [
            'header'  => "Content-type: application/x-www-form-urlencoded\r\n",
            'method'  => 'POST',
            'content' => http_build_query($data),
        ],
    ];

    $context  = stream_context_create($options);
    $result   = file_get_contents($url, false, $context);
    
    return json_decode($result, true);
}

// 2. 検証実行
$verification = verifyTurnstile($token, $remoteIp);

// 3. 結果の判定
if ($verification['success']) {
    // === 認証成功:メール送信処理 ===
    
    $to = "admin@example.com"; // 管理者のメールアドレス
    $subject = "お問い合わせがありました";
    $name = htmlspecialchars($_POST['your_name'], ENT_QUOTES, 'UTF-8');
    $email = htmlspecialchars($_POST['your_email'], ENT_QUOTES, 'UTF-8');
    
    $message = "お名前: $name\nメール: $email";
    $headers = "From: $email";

    if (mail($to, $subject, $message, $headers)) {
        echo "送信完了しました。";
    } else {
        echo "メール送信に失敗しました。";
    }

} else {
    // === 認証失敗(スパムの可能性) ===
    // エラーログ等に残す場合はここで処理
    echo "認証エラー:不正なアクセスの可能性があります。もう一度お試しください。";
    // デバッグ用: var_dump($verification);
}
?>

まとめ

Cloudflare Turnstileは、導入が非常に簡単でありながら、強力なセキュリティと優れたユーザー体験を両立できます。 自作のメールフォームや、WordPressのカスタムテンプレートでフォームを作成する際は、ぜひこのコードを参考に実装してみてください。

タイトルとURLをコピーしました