メールフォームでのスパム対策が行えるreCAPTCHA v3を、PHPのメールフォームに実装してみます。
PHP関連記事
PHPのmb_send_mailでメール送信時に、はしご高「髙」やたつさき「﨑」など旧漢字や丸数字の日本語文字化け対策をする
MySQL/MariaDBのデータをPHP側で暗号化・復号する
phpで10進数と16進数、2進数、8進数の変換と0埋め表記
WordPressの条件分岐タグでページを判別する
PHPでpreg_splitの文字化けを回避しながらテキストを改行ごとに区切ってHTMLメールをつくる
WordPressテーマアップロード時に「辿ったリンクは期限が切れています。 もう一度お試しください。」と表示される
PHPで画像アップロード時に比率を保ったまま縮小する
phpで郵便番号を正規表現で3桁・ハイフン・4桁で出力するfunction
phpで電話番号のハイフンを正規表現で出力するfunction
reCAPTCHAとは?
reCAPTCHAは、Googleが提供する画像を使った認証システムです。現在バージョンv2・v3が公開されています。
サイトからフォームで送信されるタイミングで、botなどからの悪質なアクセスからサイトを守ることができます。
どこかのサイトのフォームで送信する際に、「私はロボットではありません」というチェックボックスが表示されるのは、そのサイトがreCAPTCHAを導入しているということです。
reCAPTCHAに新しいサイトを登録する
reCAPTCHAを利用するには、Googleアカウントが必要です。
Googleアカウントがあれば、reCAPTCHAを使用する自分のサイトを登録して、APIキーの取得ができます。
サイトの登録は下記リンクから行えます。
サイト登録画面では、必要事項を入力します。
ラベル:サイトを識別するためにわかりやすい名前入力。
reCAPTCHAタイプ:今回は「reCAPTCHA v3」を選択。
ドメイン:reCAPTCHAを設置するサイトのドメインを指定。
オーナー:Googleアカウントのメールアドレスを指定。
内容を送信すると、問題なければAPIキー(サイトキーとシークレットキー)が表示されます。
サイトキーとシークレットキーとは?
サイトキーとは、reCAPTCHAを設置するフォームのHTML内に使用します。
登録したサイトを識別するもので、(コード上に出てるので)バレても問題ありません。
シークレットキーとは、サイトとreCAPTCHA間の通信で使用し、フォームから送信されたデータの整合性を確認します。シークレットキーは公開してはいけません。
サイトキーとシークレットキーを使ってHTMLとPHPで実装していきます。
必要なファイルは下記となります。
・form.php(フォーム送信用)
・sent.php(送信データ処理用)
フォーム送信用HTMLの実装
サイトキーを取得し、form.phpに下記javascriptを追記します。
この場合、ページを読み込んですぐにトークンを取得しているので、2分後にはこのトークンの有効期限が切れてしまうので注意が必要です。
JavaScript
<script src="https://www.google.com/recaptcha/api.js?render=サイトキー"></script> <script> grecaptcha.ready(function () { grecaptcha.execute("サイトキー", {action: "sent"}).then(function(token) { var recaptchaResponse = document.getElementById("recaptchaResponse"); recaptchaResponse.value = token; }); }); </script>
HTML
form.phpのformタグ内に、input[type="hidden"]
を追記します。
<form method="post" action="sent.php"> <label for="name">お名前</label><em>必須</em> <input type="text" name="name" id="name" value=""> <input type="hidden" name="recaptchaResponse" id="recaptchaResponse"> <input type="submit" value="送信"> </form>
送信データ処理用PHPの実装
シークレットキーを取得し、sent.phpに下記PHPを追記します。
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) { echo "認証成功"; } else { echo "認証エラー"; } } else { echo "不正アクセス"; }
送信されたrecaptchaResponse
が存在するかを確認し、その後シークレットキーと照らし合わせて認証処理を確認しています。
レスポンスはJSON形式で返ってくるので、json_decode()
でデコードしています。
コメント