サイトの入力フォームにreCAPTCHA v3 を導入する

スパムメールを防止するためのGoogleのサービス、reCAPTCHA v3の基本的な仕組みと使い方をメモします。

reCAPTCHAとは?

reCAPTCHAはWebサイトのお申し込みフォームなどでよく見かける「私はロボットではありません」のチェックボックスや、文字や画像を選ばせてスパムによる操作でないことを確認し、不正な投稿を防ぐ機能です。

本記事で紹介するv3のバージョンから、ユーザーが文字や画像選択のような操作を行うことなく、スパムメールであるかどうかが自動的に判別されるようになっています。

サイトへの導入手順

キーを取得する

Googleアカウントを使用してreCAPTCHAのサイトからサイトキーシークレットキーという二つの専用のパスワードを取得しておきます。

公式ページ
https://developers.google.com/recaptcha/docs/v3
hereのリンクから管理画面へ移動する。

サイトのドメインを登録、v3を選択、規約にチェックを入れて送信。

サイトキーとシークレットキーが取得されますので控えておきます。

※ ページ内、下記記載のリンクから具体的な実装方法を参照することができます。

クライアントサイドの実装方法を表示
サーバーサイドの実装方法を表示

(以降はそちらの内容をもとに実装方法を解説していきます)

フォームの実装 (トークンの取得&送信)

入力フォームへreCAPTCHAの組み込みを行います。

<!DOCTYPE html>
<html>
<head>
<title>reCAPTCHA Sample</title>
// render へサイトキーを設定する
<script src="https://www.google.com/recaptcha/api.js?render=6LeV09xxx"></script>
</head>
<body>
<h1>reCAPTCHA Sample</h1>
<form action="送信先" method="post" id="demo-form">
    <input type="text" name="name">
    <button type="submit">Submit</button>
    <input type="hidden" name="recaptchaToken" id="recaptchaToken" />
</form>
<script>
document.getElementById('demo-form').addEventListener('submit', onSubmit);

function onSubmit(e) {
    e.preventDefault();
    grecaptcha.ready(function() {
     // サイトキーを設定する
        grecaptcha.execute('6LeV09xxx', {action: 'submit'}).then(function(token) {
            // Add your logic to submit to your backend server here.
            var recaptchaToken = document.getElementById('recaptchaToken');
                    recaptchaToken.value = token;
                    document.getElementById('demo-form').submit();
        });
    });
}
</script>
</body>
</html>

(上記内、事前の準備で取得したサイトキーを埋め込んでください。)
実装を行うとページの右下のあたりに下記のreCAPTCHAのアイコンが表示されるようになります。

JavaScriptを実装してgoogleの専用サーバが発行する認証用のアクセストークンを取得し、入力情報と共にWebサーバ側へ送信します。

こちらのサンプルでは送信ボタンをクリックしたタイミングでトークンを発行、hiddenの値としてセットしています。
(仕様によりトークンの有効時間は2分間となっているようです)

サーバーサイド(PHP)の実装

リクエストを受け取るWebサーバ側では事前に取得したシークレットキーとフォームから送信されたアクセストークンを元にgoogleの専用サーバーへスパム判定の認証依頼を送り、JSON形式でレスポンスされる認証の結果を参照します。

本例ではWebサーバ側の処理をPHPで実装しています。

(認証結果例)

{
  "success": true,
  "challenge_ts": "2020-06-27T07:22:18Z",
  "hostname": example.co.jp,
  "score": 0.9,
  "action": "submit"
}
<?php

if($_SERVER['REQUEST_METHOD'] == "POST")
{
    // シークレットキーを設定
    $secretKey = '6LeV09Uaxxxx';
    
    $verifyResult = file_get_contents('https://www.google.com/recaptcha/api/siteverify?secret='.$secretKey.'&response='.$_POST['recaptchaToken']);

    $verifyResult = json_decode($verifyResult);

    if ($verifyResult->success == false)
    {
        // スパム認定された場合の処理
    }

}

scoreについて

上記の例では返却されたJSONのうち、success値の真偽によってスパムである場合の処理を実装していますが、返却値のうちのscoreの値によって判定を行うこともできます。

(例) successがtrueで合っても、scoreが閾値である※0.5を下回る場合にスパムとして扱う
※Google公式

if ($verifyResult->success == false || $verifyResult->score < 0.5)
{
    // スパム認定された場合の処理
}

Follow me!