google reCAPTCHAを使ってみようと思い、設定などをメモ
どうやら2024/8くらいに大幅な変更があったようで、今までのようにreCAPTCHAを単独で使うことが不可能になっていた。(あったのかもしれないが探せなかった。)今まで使ってたreCAPTCHAはGoogle Cloud Platform(GCP)というよくわからないところにプロジェクトが勝手に作成され、そこで管理されていた。
プラン
| プラン(全てreCAPTCHA Enterprise API上で動作) | 特徴 |
| essential | 無課金・月10,000件まで |
| standard | 課金・月1,000,000まで? |
| enterprise | 課金・無制限 |
v1はなくなり、v2とv3の方式を、essential(課金無し), standard(課金有), enterprise(課金有・評価高) などのプランで使うようになったらしい。ちなみにプランは選ぶのではなく、課金の有無と件数により自動的に決まる
以前は無料でも一か月100万回までリクエストが可能だったが1万回に減少。個人サイトならば使えるかもしれないけど、大規模なサイトだと課金が必要かもしれません。無課金で上限に達するとエラーが返されるそうです。いきなりの高額請求は課金が無効の場合は無いと思われます。
プロジェクト作成

google reCAPTCHAのページのコンソールを開き、プロジェクトがある人は左のような画面になるので、+で新規追加ができます。プロジェクトが無い方はいきなりプロジェクト作成画面に移行します。
作成画面で、
ラベル…好きな名前
reCAPTCHAタイプ…v2かv3を選択
ドメイン…reCAPTCHAを使いたいサイトのドメインを設定(後で削除や追加が可能)
GoogleCloudPlatform…プロジェクト名を設定
設定したらサイトキーとシークレットキーが取得できます。(きちんと設定が完了するまで一分くらいかかるので待った方がいいと思う)



設定が完了すると左のような画面が出るので、そこからGoogle Cloud Platformの画面へ移動できます。(サイトキーやシークレットキーはいつでもコンソールで確認できます。)

上の画面がGoogle Cloud PlatformのプロジェクトのreCAPTCHAページで、ここで保護という緑のチェックマークが出てれば大丈夫だと思います(最初は時間がかかるのかまだ設定されていないと出ていました)。それから下の方の注意ですが、自分はまだ請求先と結び付けてないので自動的に無課金の設定になっています。(でもおそらく最初は無課金プランになっているのではないかと思うのですが…一応請求先を設定している方は確認した方がいいかもしれません)。ちなみにこのGCPのページ、広大すぎてよくわかりませんでした。GCPのページからサイトキーやreCAPTCHA APIプロジェクトを作成することもできるらしいです。ここで迷ってよくわからなかったので、普通にGoogle reCAPTCHAのページから作ることをお勧めします。

コンソールの設定にもアラートをオーナーに通知などの設定があります。
AMPのチェックは、AMPページ用のreCAPTCHA専用設定なので、AMPを使わない場合はスルーしてOKです。
reCAPTCHAの実装
キーを使用して JavaScript API を読み込みます。
<head>
<script src="https://www.google.com/recaptcha/enterprise.js?render=各自のサイトキー"></script>
<!-- Your code -->
</head>//reCAPTCHA用コード
function submitForm() {
// reCAPTCHAトークンを取得
grecaptcha.enterprise.ready(function () {
grecaptcha.enterprise
.execute("サイトキー", { action: "submit" })
.then(function (token) {
// トークンをフォームに追加
var form = document.getElementById("formSubmit");
var input = document.createElement("input");
input.type = "hidden";
input.name = "g-recaptcha-response";
input.value = token;
form.appendChild(input);
// フォームを送信
form.submit();
});
});
}取得したトークンはフォームに隠し入力フィールドとして追加され、フォームの送信時に一緒に送信されます。
<?php
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
// サーバー側でreCAPTCHAトークンを検証
$secretKey = 'シークレットキー';
$token = $_POST['g-recaptcha-response'];
// reCAPTCHA検証のURL
$url = 'https://www.google.com/recaptcha/api/siteverify';
$data = [
'secret' => $secretKey,
'response' => $token,
];
// APIリクエストを送信
$options = [
'http' => [
'method' => 'POST',
'header' => 'Content-Type: application/x-www-form-urlencoded',
'content' => http_build_query($data)
]
];
$context = stream_context_create($options);
$response = file_get_contents($url, false, $context);
$responseKeys = json_decode($response, true);
// ユーザー入力データ
$name = isset($_POST['entry_000000']) ? $_POST['entry_000000'] : '';
if ($responseKeys['success'] == 1) {
// reCAPTCHA成功 → Googleフォームにデータを送信
$postData = [
'entry.000000' => $name,
];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://docs.google.com/forms/各自のフォームアクションURLへ/formResponse');
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($postData));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$googleResponse = curl_exec($ch);
curl_close($ch);
// 成功したときのコード
} else {
// reCAPTCHAが失敗した場合のコード
}
} else {
// 失敗した場合のコード
}
?>細かいコードやエラーハンドリングは省略しています。つまったのは、Google Formではnameにentry.00000などと名前をつけますが、POSTで渡されるときはentry_00000となっているので、間違いやすいです。
reCAPTCHAが動作する仕組み
AIの答えで恐縮ですが、自分よりも全然賢いので引用します。
送信ボタンが押されたとき(JavaScriptで処理)
JavaScriptの grecaptcha.enterprise.execute を使用して、GoogleのreCAPTCHAサーバーから トークン を取得しています。このトークンは、その操作(action: "submit")や、Googleが収集したユーザーの行動データ(マウス操作、キー入力、ブラウザ環境など)を基に生成されます。
※ちなみにこのとき設定した{ action: “submit” }は、submitなのかloginなのか情報をこちらが渡しているだけで、あとからサーバーの処理で検証するために入れています。
このトークンには
- ユーザーの操作履歴(マウスの動き、クリック、入力速度など)
- ブラウザとデバイス情報
- IPアドレス(位置情報など)
- reCAPTCHAの実行時に指定されたアクション
などの情報が入っており、Googleはこれらを分析し、人間かボットかを判断した結果をレスポンスとして返します。
サーバー側での処理(PHPで検証)
- フォームが
submit.php(アクション等で設定)に送信されると、PHPコードが実行されます。 - サーバー側では以下の手順でロボットか人間かを判断します:
- reCAPTCHAの検証リクエストをGoogleに送信
- Googleのレスポンスを取得
Googleは、以下の情報を含むJSONレスポンスを返します:score: 0.0(ボット)〜1.0(人間)のスコアaction: JavaScript側で指定したaction値(例: “submit”)success: トークンが有効かどうか(trueなら有効)
その他のメタデータ
- 検証条件を確認
レスポンスを確認し、successがtrueであることをチェックします
成功ならフォームデータを送信、失敗ならエラーを返すようにします
雑なまとめ
送信などのボタンを押したときにreCAPTCHAからトークン(ユーザーの行動などの情報)を取得し、サーバーでapiを叩き、そのスコアを判定してもらい、人間だと判定したら(スコア0.5以上など)フォームデータをGoogleFormに渡しています。

