PHP で Google reCAPTCHA v3 付きのお問い合わせフォームを作る (1)


はじめに

Google reCAPTCHA v3 を付けたお問い合わせフォームを PHP で作っていきます。
メール送信ライブラリは Swift Mailer を使用します。
reCAPTCHA v3 については こちら

Google reCAPTCHA v3 とは

巷でよく見かける 私はロボットではありません と書かれたチェックボックスの新しいバージョンです。
ですが、 チェックを付けたり、写真を選んだりする必要がなくなりました。
その代わりに、ユーザの行動から 0.0~1.0 のスコアが算出され、 0 に近いほどロボットによる操作の疑いが強く、 1 に近いほど人間による自然な操作の可能性が高いということみたいです。

前提条件

  • PHP 7.3 (これより低くても可)
  • Composer をインストールしておく

事前準備

reCAPTCHA v3 のキーを取得する

まず、 こちら から reCAPTCHA v3 の Admin console にアクセスします。
はじめて Admin console を開いた場合、「新しいサイトを登録する」という画面がされるので、ラベル・reCAPTCHA タイプ(reCAPTCHA v3)・ドメインを入力します。
ラベルは任意の名前で構いません。ドメインは使用するサイトのドメイン、またはローカル開発環境であれば localhost 等を入力してください。
最後に「reCAPTCHA 利用条件に同意する」にチェックを入れて「送信」を押します。
サイトキー と シークレット キー が表示されたらコピーしておきます。

Composer で使用するパッケージをインストールする

使用するパッケージは以下の2つです。

  1. reCAPTCHA PHP client library (Google 公式)
  2. Swift Mailer

composer require でパッケージをダウンロードします。

composer require google/recaptcha && composer require swiftmailer/swiftmailer

パッケージのダウンロードが終わったらひとまず準備は完了です。
ここから実際にコードを書いていきます。

導入手順

1. HTML でフォームを作る

まずは HTML でシンプルなお問い合わせフォームを作っていきます。

index.php
<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>お問い合わせフォーム</title>
</head>
<body>
  <form action="send.php" method="POST" name="inquiry">
    <p>
      <label for="name">お名前</label>
      <input type="text" name="name" id="name">
    </p>
    <p>
      <label for="email">メールアドレス</label>
      <input type="email" name="email">
    </p>
    <p>
      <label for="contents">お問い合わせ内容</label>
      <textarea name="contents" id="contents" cols="30" rows="10"></textarea>
    </p>
    <button type="submit">送信する</button>
  </form>
</body>
</html>

2. reCAPTCHA トークンの生成

ここで事前準備の際に取得した サイトキー が必要になります。
JavaScript でトークンの生成とトークンをフォームに hidden で配置するコードを </body> の直前に書いていきます。
<サイトキー> のところは取得したサイトキーを入れてください。
{action: 'inquiry'}inquiry は任意のもので構いません。

index.php
<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>お問い合わせフォーム</title>
</head>
<body>
  <form action="send.php" method="POST" name="inquiry">
    <p>
      <label for="name">お名前</label>
      <input type="text" name="name" id="name">
    </p>
    <p>
      <label for="email">メールアドレス</label>
      <input type="email" name="email">
    </p>
    <p>
      <label for="contents">お問い合わせ内容</label>
      <textarea name="contents" id="contents" cols="30" rows="10"></textarea>
    </p>
    <button type="submit">送信する</button>
  </form>

  <script src="https://www.google.com/recaptcha/api.js?render=<サイトキー>"></script>
  <script>
    grecaptcha.ready(function() {
      grecaptcha.execute('<サイトキー>', {action: 'inquiry'}).then(function(token) {
        var rcpt = document.createElement('input');
        rcpt.type = 'hidden';
        rcpt.name = 'token';
        rcpt.value = token;
        document.inquiry.appendChild(rcpt);
      });
    });
  </script>
</body>
</html>

3. reCAPTCHA v3 のスコアを算出して処理を分岐する

フォームからの POST を受け取って、PHPで処理していきます。
ここで事前準備で取得した シークレット キー<シークレット キー> に入れます。
setExpectedAction('inquiry')inquiry は、先ほどトークン犯行の際に指定した {action: 'inquiry'} と同じ名前にします。

ここからが一番重要です。 setScoreThreshold(0.5)0.5 は、人間とロボットを分ける閾値です。
ここの数値が 1 に近いほど厳しい判定になり、 0 に近いほど緩い判定になります。

send.php
<?php
require_once __DIR__ . '/vendor/autoload.php';
use ReCaptcha\ReCaptcha as ReCaptcha;

if ($_POST['token']) {
  $response = (new ReCaptcha('<シークレット キー>'))
                  ->setExpectedHostname($_SERVER['SERVER_NAME'])
                  ->setExpectedAction('inquiry')
                  ->setScoreThreshold(0.5)
                  ->verify($_POST['token'], $_SERVER['REMOTE_ADDR']);
  $result = $response->toArray();

  if ($result['success']) {
    echo 'あなたはロボットではありません。';
  } else {
    echo 'あなたはロボットです。';
  }
}

ここまでが reCAPTCHA v3 の基本的な使い方です。

続き → PHP で Google reCAPTCHA v3 付きのお問い合わせフォームを作る (2)