お問い合わせフォームにreCAPTCHA v3を導入してみました!

f:id:moshimore:20190201151826j:plain
近頃、お問い合わせフォームからのスパムが多くなってきたので、reCAPTCHAを導入してみました。

reCAPTCHAとは

今さらの話になってしまいますが、reCAPTCHAとはGoogleが提供しているスパムによる問い合わせフォームの送信や不正なトラフィックを防止するためのサービスです。
よく目にする「ロボットではありません。」が、この機能の1つです。

reCAPTCHAの種類

さて、reCAPTCHAの最新版は第3世代になり、従来型のようにユーザーの手間や邪魔にならないような仕組みになりました。
具体的にはサイトを巡るユーザーの動きを追跡して、それが人なのかロボットなのかをスコア化して、それをスパムかどうかの判断基準にします。

参考までに第1世代は、ロボットには読みにくいグニャグニャしたアルファベットを読ませるタイプです。
このタイプは、2018年3月31日にサービスを終了しています。
人にとっても非常に読みにくくて使いづらいサービスでした。
f:id:moshimore:20190201145532p:plain

第2世代は、「ロボットではありません。」にチェックを入れたり、画像を選んだりするタイプです。
こちらのタイプは、まだ現役で稼働していますね。
f:id:moshimore:20190201145912g:plain

reCAPTCHA v3の登録方法

最初にreCAPTCHAのページから利用するサイトの情報を入力していきます。

f:id:moshimore:20190201154659p:plainf:id:moshimore:20190201154707p:plain
  • ラベル

登録したサイトを識別できるようにするためのラベルです。
サイト名などを入力しておきます。

  • reCAPTCHA タイプ

今回はreCAPTCHA v3を選択しておきます。

  • ドメイン

ここで入力したドメインとサブドメインで使用できるようになります。
つまり、domain.comを登録しておけば、subdomain.domain.comでも使用できます。

  • アラートをオーナーに送信する

設定エラーや不審なトラフィックの増加など、サイトで問題が検出された場合にアラートを受け取れます。

あとは、送信ボタンを押せば、登録完了です。

f:id:moshimore:20190201160811p:plainf:id:moshimore:20190201160815p:plain

サイトキーとシークレットキーは後々使用するのでコピーしておきます。

reCAPTCHA v3の導入方法

公式ガイドは以下のページになりますが、若干分かりづらいところが多かったので、コピペで導入できるように記載していきます。
developers.google.com

headタグ内に以下を設定します。

<script src="https://www.google.com/recaptcha/api.js?render=サイトキー"></script>
<script>
    grecaptcha.ready(function () {
        grecaptcha.execute('サイトキー', {action: 'homepage'}).then(function(token) {
            var recaptchaResponse = document.getElementById('recaptchaResponse');
            recaptchaResponse.value = token;
        });
    });
</script>

formタグ内に以下を設定します。

<input type="hidden" name="recaptchaResponse" id="recaptchaResponse">

PHPの場合はPOSTの受け取りで以下のように処理します。

<?php
if (isset($_POST['recaptchaResponse']) && !empty($_POST['recaptchaResponse']))
{
$secret = 'シークレットキー';
$verifyResponse = file_get_contents('https://www.google.com/recaptcha/api/siteverify?secret='.$secret.'&response='.$_POST['recaptchaResponse']);
$reCAPTCHA = json_decode($verifyResponse);
if ($reCAPTCHA->success)
{
// OK
}
else
{
// NG
}
}
else
{
// ERROR
}
?>

$reCAPTCHAオブジェクトは、以下のようになっています。
successがtrueの場合はトークンが有効であると判断でき、その後にscoreの値を確認します。
scoreの値は0.0~1.0までの間で設定されていて、0.0に近いほどスパムである可能性が高くなります。

{
["success"]=> bool(true)
["challenge_ts"]=> string(20) "2019-02-01T05:33:31Z"
["hostname"]=> string(12) "domain.com"
["score"]=> float(0.9)
["action"]=> string(8) "homepage"
}

successがfalseの場合はerror-codesが設定されます。

エラーコード 説明
missing-input-secret シークレットキーがありません。
invalid-input-secret シークレットキーが有効ではありません。
missing-input-response トークンがありません。
invalid-input-response トークンが有効ではありません。
bad-request 無効なリクエストです。
timeout-or-duplicate トークンが期限切れ、または使用済みです。

まとめ

今回は、PHPで作られたページに実装してみましたが、似たようなコードで他の言語にも組み込めると思います。
非常に簡単にスパム対策が行えるので、使わない手はないサービスですね。

以上、お問い合わせフォームにreCAPTCHA v3を導入してみました!でした。