最近の世界情勢の影響なのかスパムが多くなった気がするので、reCAPTCHAを使ってフォームのスパム対策を実装してみます。
reCAPTCHAとはGoogleが提供するスパム対策サービスです。
reCAPTCHA | Google Developers
お問い合わせフォームや、会員登録フォームなどに設置される「私はロボットではありません」チェックボックスや、9枚ほど画像が表示されて「この中から車の画像を全て選択してください」というやつですね。
これらはreCAPTCHA v2で、ユーザの操作や判断の手間が1つ増えることになります。人によっては、この手間が不快に感じる方もいらっしゃるはずです。コンバージョン率低下の懸念がありますね。
それに対して、reCAPTCHA v3はプログラム側(AI)でスパムかどうかを判断するので、ユーザへの影響はほとんどありません。
サイト登録
Goolgeアカウントでサインインした状態で、以下のページにアクセスします。
reCAPTCHA
メニュー「v3 Admin Console」をクリックして、サイトを登録します。
- ラベルには任意で分かりやすいラベル名をセットします
- reCAPTCHAタイプは「reCAPTCHA v3」を選択します
- ドメインにはAPIを使用するドメインをセットします。ローカルで開発、テストなどする場合は「localhost」も有効です。
利用条件に同意して送信します。送信時に発行される「サイトキー」と「シークレットキー」を控えておきます。
フロント側の実装
対象となるページに以下のスクリプトを埋め込みます。パラメータ「render」には取得したサイトキーをセットします。
<script src="https://www.google.com/recaptcha/api.js?render=(サイトキー)"></script>
例えば「id=”form”」のformタグ内に取得したトークンを保持するためのhiddenタグを用意しておきます。
<input type="hidden" name="recaptchaToken" id="recaptchaToken">
次にフォーム送信ボタン押下時に、トークンを取得し、上のhiddenタグにセットするスクリプトを実装します。こちらにもサイトキーをセットします。
<script> document.getElementById('form').addEventListener('submit', onSubmit); function onSubmit(e) { e.preventDefault(); grecaptcha.ready(function() { grecaptcha.execute('(サイトキー)', {action: 'submit'}).then(function(token) { var recaptchaToken = document.getElementById('recaptchaToken'); recaptchaToken.value = token; document.getElementById('form').submit(); }); }); } </script>
フロントの実装は以上です。
サーバ側の実装
フロントからのリクエストをキャッチしたサーバサイドのPHP処理です。
フロントで取得したトークンとシークレットキーをパラメータに、APIに認証をリクエストします。
if(isset($_POST["recaptchaResponse"]) && !empty($_POST["recaptchaResponse"])){ $res_json = file_get_contents("https://www.google.com/recaptcha/api/siteverify?secret=" . (シークレットキー) . "&response=" . $_POST["recaptchaResponse"]); $res = json_decode($res_json); if($res->success){ // 認証成功 if($res->score > 0.5){ // 0.5点より上は正常処理 }else{ // スパム判定 } }else{ // 認証エラー } }
認証に成功するとsuccessにtrueがセットされます。
同時に、0~1点のスコアが返ってくるので、このスコアを元にスパムかどうかを判定します。
0点に近いほど、スパムである疑いが強いです。判定基準は任意で、この例では0.5点より大きければ「スパムではない」と判断しています。
ちなみに、先ほどのreCAPTCHA管理画面で、何件アクセスがあったのか、各スコアがどうだったのかななど、解析レポートを確認することができます。
コメントする