はじめに
とある日からお問合せフォームからスパムメールが大量に送られてくるようになりました。
qq.comのドメインから中国後で書かれた解読不能なメールが1分間に何10件も、、、
その対策として導入したキャプチャ認証のreCAPTCHAを入れてからスパムメールはピタリと止まりました。
今回はそのreCAPTCHAの設定方法の共有記事になります。
やること
おおまかにですが、以下を対応します。
・reCAPTCHAにサイトを登録
・HTML上の実装
・PHPを使った検証
reCAPTCHAにサイトを登録
ラベル
これは識別用に管理しやすい名前を入れます
reCAPTHAタイプ
今回はreCAPTHAタイプをv2を選択
「私はロボットではありません」チェックボックスを選択
ドメイン
認証を入れたドメインを入れる
オーナー
オーナーは自分だけであればそのままでOK
送信まで
利用条件に同意してアラートにオーナーに送信するかどうかを選び
最後に「送信」を押下
API キー取得
入力に問題がなければ、APIキー(サイトキーとシークレットキー)が表示されるのでコピーしておきます。APIキーは recaptcha/admin で後から確認することができます。
Site Key : reCAPTCHAを表示する際に使用するサイトのキー
Secret Key : 検証で使用する秘密のキーで公開してはいけません。
これでサイト登録は完了!
HTML上の実装
今回はこのように作成しましたという一例です。
g-recaptchaタグを使って表示
<html lang="ja">
<head>
<title>g-recaptcha タグを使って表示</title>
<script>
var verifyCallback = function(response) { //コールバック関数の定義
//#warning の p 要素のテキストを空に
document.getElementById("warning").textContent = '';
//#send の button 要素の disabled 属性を解除
document.getElementById("send").disabled = false;
};
var expiredCallback = function() { //コールバック関数の定義
//#warning の p 要素のテキストに文字列を設定
document.getElementById("warning").textContent = '送信するにはチェックを・・・';
//#send の button 要素に disabled 属性を設定
document.getElementById("send").disabled = true;
};
</script>
</head>
<body>
<h1>g-recaptcha タグを使って表示</h1>
<form method="post" action="?">
<div class="g-recaptcha" data-sitekey="サイトキー" data-callback="verifyCallback" data-expired-callback="expiredCallback"></div>
<p id="warning">送信するにはチェックを入れてください。</p>
<button id="send" type="submit" disabled>送信</button>
</form>
<script src="https://www.google.com/recaptcha/api.js" async defer></script>
</body>
</html>
サイトキーのところには先ほど取得した Site Key を入れてください
この記述で見た目上のチェックボックスが出来上がりました。
g-recaptcha-response(レスポンス)
ユーザがウィジェットにチェックを入れて成功すると、API により以下のようなレスポンス(トークン)が生成されます。
03AERD8Xr85M-qcg5EoivhRUI9RgNagFmqwGUKZcXupYI_2tcBLncMtupBlxGiT4C0YYOUI7R4k3o
NX4OCYI9kq83tmTqG1MuNEIexHli-qNd5FLE7XKpOi3Tliy5ZVUFmaeg1qwCnzGUKn1Pd7ae79xn
・・・中略・・・
PEn1Pd7ae9fX_aeg1fNQME9mNNCnzMp8_ATvQ
この値を使ってサーバ側で検証を行います。この値は以下の方法で取得することができます。
コールバック関数のパラメータ: function(response) の response
grecaptcha.getResponse メソッド(返り値)
フォームを送信した際に生成される $_POST["g-recaptcha-response"]
このレスポンス(g-recaptcha-response)はトークンとも呼ばれ、有効期間は2分間です。
今回はフォームを送信した際に生成される $_POST["g-recaptcha-response"]
を使ってPHPで検証します。
PHPを使った検証
reCAPTCHA を設置しただけでは意味がないので、サーバ側でレスポンスがユーザにより生成されたものかを検証する必要があります。
以下のような流れで判定します。
・ユーザのレスポンス(トークン)を取得($_POST[ 'g-recaptcha-response' ])
・API を使ってトークンを検証(API にトークンを送信して検証結果を取得)
・API から取得した値(検証結果)を基に判定
フォーム送信後の完了画面などでPHPで実装しました。
$recaptcha = $_POST['g-recaptcha-response'];
if (isset($recaptcha)) {
$captcha = $recaptcha;
} else {
$captcha = '';
}
$secretKey = "シークレットキー";
$url="https://www.google.com/recaptcha/api/siteverify?secret={$secretKey}&response={$captcha}";
$ch = curl_init();
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt( $ch, CURLOPT_URL, $url );
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
$result = curl_exec( $ch );
curl_close($ch);
$resp_result = json_decode($result,true);
if(intval($resp_result["success"]) !== 1) {
// reCAPTCHA承認失敗時の処理
header('Location: サイトURL');
exit;
}
シークレットキーのところには先ほど取得した Secret Key を入れてください
サイトURLのところには設定したい失敗時の遷移先をいれてください(エラーメッセージを出すに変えてもいいですね)
file_get_contents() か cURL 関数を使って取得できます。
今回は cURL 関数を使いました。
これで設定完了になります。
結果確認
検証の結果を受け取れています。
目的はスパムメール対策でしたがこれで綺麗に止まったためひとまず安心です。
参考
https://www.webdesignleaves.com/pr/plugins/google_recaptcha.php
https://www.hai2mail.jp/column/2020/0509.php