仕事でreCAPTCHA v3を導入したので、その際のメモです。
このサイトとかでも導入しているのですが、このサイトに導入したときはプラグインで一瞬だったので特に何もなかったのですが、今回はPHPでサーバー側の処理なども行いました。
前提として、Googleのアカウントを取得済みで進めます。
reCAPTCHAの設定
reCAPTCHA: Easy on Humans, Hard on Bots ここのサイトの右上の「Admin Console」から管理画面に入ります。
今までサイトを登録したことがなければ、新しいサイトの登録画面が表示されます。
すでにサイトが登録済みで、新規で作成する場合は、管理画面トップの右上部にある歯車マークの横の「+」ボタンを押すと、新規サイト登録画面になります。
登録の項目を見ていきます。
ラベル
好きな内容を入れてください。placeholderにもある通り、サイトのドメインなどがわかりやすいと思います。
reCAPTCHA タイプ
reCAPTCHAのv2もしくはv3を選択します。
v2は「私はロボットではありません」にチェックを入れるなど、ユーザーに入力を求める物などです。
未検証ですが、「非表示 reCAPTCHA バッジ」はv3と同じような事ができるかもしれないです。
今回は、v3を選択します。
ドメイン
設置するサイトのドメインを入力します。
example.comを入力した場合は、hoge.example.comなどのサブドメインも有効になります。
複数のサイトで同じ設定を利用する場合は、ここに追加していきます。
テストサイトと本番サイトを両方含める事は可能ですが、個人的には分けた方が良いかと思います。
オーナー
オーナーは、この設定の共有するメールアドレスを登録します。
reCAPTCHA 利用条件に同意する
同意しましょう。
アラートをオーナーに送信する
設定エラーなどがあった場合、オーナーにアラートが送信されます。
お好みでどうぞ。
サイトキーとシークレットキーの確認
設定が完了すると、サイトキーとシークレットキーが表示されます。
このキーを組み込みの際に使用します。
また、再度キーを確認したい場合は、管理画面トップの右上部にある歯車マークから設定画面にいき、「reCAPTCHAのキー」の項目で確認できます。
検証の流れ
reCAPTCHAv3の検証の流れとしては以下になります。
- JSにてサイトキーを使ってトークンを発行
- トークンをバックエンドの処理に送信
- バックエンドで渡されたトークンとシークレットキーを使って検証
フロント側の実装
まずはトークンを取得するために、reCAPTCHAを導入したいページのHTMLにJSを組み込みます。
JSでAPIからトークンを取得し、hiddenにセットし、POSTで送信できるようにします。
サイトに応じて、適切な場所に配置してください。
<form action="sample.php" method="post">
<input type="submit" value="送信">
<input type="hidden" name="recaptchaToken" id="recaptchaToken" />
</div>
</form>
<script src="https://www.google.com/recaptcha/api.js?render={サイトキー}"></script>
<script>
grecaptcha.ready(function() {
grecaptcha.execute('{サイトキー}', {action: 'homepage'}).then(function(token) {
var recaptchaToken = document.getElementById('recaptchaToken');
recaptchaToken.value = token;
});
});
</script>
サイトキーは、そのまま記載しても良いですが、実際はPHP側でViewに渡すようにしています。
設置されると、右下にreCAPTCHAのバッジが表示されます。
バックエンドの実装
渡されたトークンを元に検証を行います。
$params = array(
'secret' => {シークレットキー},
'response' => {渡されたトークン},
);
$url = 'https://www.google.com/recaptcha/api/siteverify?';
$url .= http_build_query($params);
$ch = curl_init();
curl_setopt( $ch, CURLOPT_URL, $url );
curl_setopt( $ch, CURLOPT_HEADER, false );
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
curl_setopt( $ch, CURLOPT_TIMEOUT, 120 );
$response = curl_exec( $ch );
curl_close( $ch );
$verify = json_decode($response);
if($verify->success) {
// 検証成功
} else {
// 検証失敗
}
実際のソースを抜粋してちょっと改変していますが、概ねはこんな感じになります。
他のサイトを見ると、file_get_contentsで取得しているところが多いですが、ステージング環境にてfile_get_contentsがnullしか返さないため、cURLで取得するように変更しました。
php.iniのallow_url_fopenの設定も見直したのですが、うまくいかず。。。
GETパラメータで渡されたトークンとシークレットキーをGETで検証URLに渡し、検証した結果をsuccessで判定します。
successはtrueもしくはfalseが返されます。falseの場合は、error-codesでエラーの内容が取得できます。
マニュアルにあるエラーコードは下記になります。
※ マニュアルからGoogle翻訳で翻訳した物です。
error-codes | 内容 |
---|---|
missing-input-secret | シークレットキーがない |
invalid-input-secret | シークレットキーが無効か、形式が正しくない |
missing-input-response | トークンがない |
invalid-input-response | トークンが無効であるか、形式が正しくない |
bad-request | リクエストが無効であるか、形式が正しくない |
timeout-or-duplicate | タイムアウトまたは重複 |
こんな感じで、reCAPTCHAv3を実装してみました。
トークンloginとかsocialとか他のactionもあるようなので、機会があれば試してみたいと思います。