
こんにちは、aoyamaです。
うーん、PHPで作ったフォームにスパムメールが大量に届いて困るなー。Contact Form7だったらインテグレーションの所でGoogle reCAPTCHAを一瞬で入れて終わりだけどPHPフォームの場合どうしたらいいんだろう?
今回は上記のお悩みを解決します。
WordPressでWEBサイトを作ると必ずと言っても良いほど届くスパムメール。
Contact Form7を使っているサイトであればパパっと設定すれば5分くらいで終わる内容ですが、PHPで作られているフォームの場合どうすればいいのでしょうか?
僕自身とある企業様よりこのようなご相談を始めてお受けして、ご対応させていただきましたので同じような課題を持つ方の参考になれば嬉しいです。
早速見ていきましょう!
目次
PHPで作られたフォームでreCAPTCHA v3を設定してみる
それでは早速ですが、ステップとしては以下になります。
①reCAPTCHAコンソールでサイトキーとシークレットキーを取得する
②サイトキーを
内で読み込む③フォーム送信前にreCAPTCHAトークンを取得し、フォームに追加する
④PHPでreCAPTCHAトークンを検証する(シークレットキーを使う)
①reCAPTCHAコンソールでサイトキーとシークレットキーを取得する
まずはじめにreCAPTCHAコンソールにアクセスし、サイトキーとシークレットキーを取得します。

上記の画面で、ラベル、ドメインを入力して進むとサイトキーとシークレットキーを取得することができます。
ここまではContact Form7を使う時と同じですね。
②サイトキーを<head>内で読み込む
取得したサイトキーを使って、以下のように<head>
内にreCAPTCHAのスクリプトを読み込みます。
<script src="https://www.google.com/recaptcha/api.js?render=サイトキーを入れます"></script>
③フォーム送信前にreCAPTCHAトークンを取得し、フォームに追加する
次にフォーム送信前にreCAPTCHAトークンを取得し、フォームに追加しましょう。
<script>
document.addEventListener('DOMContentLoaded', function () {
const form = document.querySelector('.js-form');
if (!form) return;
form.addEventListener('submit', function (e) {
e.preventDefault(); // 通常送信を防止
grecaptcha.ready(function () {
grecaptcha.execute('6LfnvHUrAAAAABLoscMrpHORpfPiZbVEJK5qHq8M', { action: 'submit' })
.then(function (token) {
// すでにあれば削除
const existingToken = form.querySelector('input[name="g-recaptcha-response"]');
if (existingToken) existingToken.remove();
// トークンをhiddenで追加
const input = document.createElement('input');
input.type = 'hidden';
input.name = 'g-recaptcha-response';
input.value = token;
form.appendChild(input);
form.submit(); // トークン付きで再送信
});
});
});
});
</script>
この処理によって、reCAPTCHA v3のトークンを取得し、<input name="g-recaptcha-response">
としてフォームに自動追加することができます。
※ここで取得したトークンは、HTML上では見えませんが、JavaScriptでフォームに自動的に追加されます。
この値を使って、次のステップ④でサーバー側で「本当に人間の操作かどうか?」を確認することができます。
④PHPでreCAPTCHAトークンを検証する(シークレットキーを使う)
JavaScriptで取得したトークンは、実はそれだけでは無効です。
Googleに「このトークン、本物ですか?」と聞いて検証する処理がPHP側に必要です。
以下のコードを、PHPのフォーム処理ファイルに追加しましょう。
<?php
// reCAPTCHAトークンが送られてきているか確認
if (!isset($_POST['g-recaptcha-response'])) {
exit('不正なアクセスです');
}
// トークンとシークレットキーを変数に格納
$recaptcha_token = $_POST['g-recaptcha-response'];
$recaptcha_secret = 'ご自身のシークレットキー';
// Googleの検証APIへリクエストを送信
$recaptcha_response = file_get_contents('https://www.google.com/recaptcha/api/siteverify?' . http_build_query([
'secret' => $recaptcha_secret,
'response' => $recaptcha_token,
'remoteip' => $_SERVER['REMOTE_ADDR']
]));
// JSONレスポンスを連想配列としてデコード
$recaptcha_result = json_decode($recaptcha_response, true);
// スコアやアクションを確認し、条件に合わなければ処理を中止
if (
!$recaptcha_result['success'] ||
$recaptcha_result['score'] < 0.5 || // スコアが0.5未満はスパムの可能性
$recaptcha_result['action'] !== 'submit' // JS側と同じ'action'である必要あり
) {
exit('スパムの可能性があるため送信できませんでした');
}
// ★ここまで通過すれば、フォーム処理を続行してOK!
このPHPコードをフォーム処理の冒頭に入れることで、「明らかにスパムっぽい送信」はブロックできるようになります。
あとは、通常のバリデーション処理やメール送信処理をこの下に書いていくだけでOKです。
「サーバー側でシークレットキーを使ってトークンをGoogleに送信し、正当性を検証する」のがこのステップです。
スコアやアクションもチェックして、スパムっぽい送信をブロックします。
注意点
①score < 0.5
という判定はあくまで目安です。
気になる場合は var_dump($recaptcha_result);
で確認してみましょう。
②action
は JS 側のgrecaptcha.execute('SITE_KEY', { action: 'submit' })
と一致させる必要があります。
③シークレットキーは絶対にHTMLやJavaScript(フロント側)には書かず、サーバー側でのみ使用してください。外部に漏れると、不正利用されるリスクがあります。
最後に
以上で、PHPフォームにGoogle reCAPTCHA v3を導入する手順は完了です!
スパムが減ることで、お問い合わせ対応の効率もグッと改善するはずです。
僕も実際に導入後、迷惑メールが激減しました。
この記事が、同じように悩んでいる方の助けになれば嬉しいです!