フリーのBootstrapテンプレート等でよく見かける基本的なバリーデーションのみで、かつ確認画面なしのシンプルなメールフォームは、スパムbotの標的になりやすいようです。今回はスパムbotを簡単に撃退できるGoogle reCAPTCHA(v3)の導入方法をサンプルコード付きで解説します。
目次
- reCAPTCHA v3の特徴
- reCAPTCHAのサイトの登録方法
- フォームと送信プログラムの改修
- まとめ
1.reCAPTCHA v3の特徴
reCAPTCHAとは、元々はウェブサイトの制限エリアへのアクセスを試みるbotからサイトを防御するための仕組みで、2007年にカーネギーメロン大学で開発されたシステムを2009年にGoogleが買い取って更に発展させてきたシステムです。
制限エリアへのアクセスを試みるbotは、無作為にフォームの送信プログラムにもアクセスしてくるため、その影響はログインシステムだけでなく、メールフォームにも影響が及びます。
reCAPTCHAの当初のバージョンでは、フォーム送信者が画像の難読文字列を判読してフォームに入力してもらうようなシステムでしたが、高度化するbotに応じてバージョンごとに進化してきました。v2では、フォーム送信者に「私はロボットではありません」というチェックボックスをチェックしてもらい、botと疑われる場合にのみ画像問題を表示する仕様でしたが、v3では、チェックの必要がない更にシンプルな仕様に変更されました。bot判定AIの進化のお陰で、v3ではフォーム送信者にほとんど負担をかけることなくbot対策ができる優れたシステムに進化しています。
2.reCAPTCHAのサイトの登録方法
では、早速導入方法に進みましょう。まず最初にGoogle reCAPTCHAアクセスして、サイトの登録を行います。

アクセスしたら、画面右上の「Admin console」にアクセスしてサイトを登録しましょう。

- ラベル …サイト名やドメインなどを入力します
- reCAPTCHAタイプ …現時点で最新のv3を選択します
- ドメイン …登録するサイトのドメインを入力します
まずは必要な情報を入力しましょう。上記の画面を参考に入力してみてください。入力が完了したら「送信」をクリックしましょう。
画面遷移後にサイトキーとシークレットキーがそれぞれ発行されるので控えておいてください。

3.フォームと送信プログラムの改修
今度は、フロント側のhtmlとサーバー側の送信プログラムに改修を施しましょう。この記事ではサーバー側の送信プログラムはphpを想定しています。
フロント側の改修
まず、既存フォームに下記のようなhiddenのフォームを追加しておきます。
<input type="hidden" id="recaptcha" value="">
さらにbodyタグの最下部に下記のJavaScriptを仕込んでおきます。
<!-- Google reCAPTCHA -->
<script src="https://www.google.com/recaptcha/api.js?render=_____入手したサイトキー_____"></script>
<script>
$(function(){
// reCAPTCHA実行
grc();
setInterval(grc, 60000);
function grc() {
grecaptcha.ready(function() {
grecaptcha.execute('_____入手したサイトキー_____', {action: 'homepage'})
.then(function(token) {
// トークン取得に成功
$('#recaptcha').val(token);
console.log('token = ' + token);
}, function(reason) {
// トークン取得に失敗
alert('誠に恐れ入りますが、現在メンテナンス中のためメールフォームの送信ができません。');
});
});
}
});
</script>
reCAPTCHAのapiにアクセスしたら、発行されたトークンをhiddenにしてあるrecaptchaに流しておいて、自分で用意した送信プログラムに渡すのがこのJavaScriptの役割です。トークン取得に失敗した際の処理なども加えておくと親切かもしれません。
トークンを受け取るために「action」を指定しますが、今回はメールフォームにちょっかいを出してくるbotを撃退する目的なので「homepage」を指定しておきます。
なお、reCAPTCHAはトークンが発行されてから、5分でタイムアウトするようです。つまり、ページを開いてから5分以降にフォームが送信された場合、トークンは無効となりbot判定されません。それを防ぐため、サンプルコードでは、setInterval関数で60秒毎ににトークンを発行しています。他の書き方もあると思いますが、何らかのタイムアウト対策は必要だと思います。
サーバー側の改修
今度は送信プログラムの改修です。フォームから送信されてきたトークンを再びapiにpostして認証を受けます。するとはapiは「success」や「score」等の判定結果をjsonで返してきます。
<?php
$url = 'https://www.google.com/recaptcha/api/siteverify';
$post_data = array(
'secret' => '_____入手したシークレットキー_____',
'response' => $_REQUEST['recaptcha']
);
$options = array(
'http' => array(
'method' => 'POST',
'header' => 'Content-type: application/x-www-form-urlencoded',
'content' => http_build_query($post_data),
)
);
$context = stream_context_create($options);
$r = json_decode(file_get_contents($url, false, $context));
var_dump($r->success);
var_dump($r->score); // Googleが定める非botのしきい値は0.5以上
// if ($r->success == 1) {
if ($r->score >= 0.5) {
// 認証成功した場合の処理
} else {
// 認証失敗した場合の処理
}
「success」で判定させる場合は「1」が人間の判定です。v3から追加された「score」で判定させる場合は、人間のしきい値が「0.5」以上となっています。
今回のサンプルコードはphpですが、他の言語の場合は上記の流れを参考に書き換えてみてください。送信プログラムの改修が完了したら、フォームからテスト送信してみましょう。条件によってこの値は変わるはずですが、通常は「0.9」を返してくるようです。
4.まとめ
従来のフォームにちょこっと手を加えるだけで、こんな簡単にbotを撃退できるGoogle reCAPTCHAは本当に便利ですね!しかも現時点で最新のv3では、フォーム送信者にほとんど負担をかけることのない仕様となっています。botに悩まされているなら今すぐ実装してみましょう。