# Google Invisible reCAPTCHA 導入手順 ## サイトの登録 登録用のGoogleアカウントにログイン https://www.google.com/recaptcha/intro/v3.html 上記ページへアクセスし、サイトを登録 | 項目名 | 入力内容 | | -------- | -------- | | **【ラベル】** | 任意の分かりやすい文字列を設定(ドメインなど)<br>例)hikari-n | | **【reCAPTCHA タイプ】** | 『reCAPTCHA v2』→『非表示 reCAPTCHA バッジ』を選択 | | **【ドメイン】** | 適用する商材の「本番・検証・ローカル」のドメイン名を入力<br>例)<br>test.jp<br>test.dev.jp<br>test.jp.localhost | | **【オーナー】** | 「メアド」・通知オン | | **【セキュリティ設定】** | ユーザーの負担が最小 | 登録が完了すると『サイトキー』と『シークレットキー』が発行されます ## フロントエンド ### ①CDNを読み込む ```htmlmixed= <!-- ReCAPTCHAタグ --> <?php if(!(isset($_GET['test_recaptcha']) && $_GET['test_recaptcha'] == 0)): ?> <script src="https://www.google.com/recaptcha/api.js" async defer></script> <?php endif; ?> ``` ```?test_recaptcha=0```というパラメータが付いている場合のみ CDNを読み込まないように設定します > 公開用にパラメータ変更済み ### ②submitボタンと利用判定用のタグ設置 ```htmlmixed= <?php if( !(isset($_GET['test_recaptcha']) && $_GET['test_recaptcha'] == 0) ): ?> <input type="submit" value="送信する" class="g-recaptcha" data-sitekey="【サイトキー】" data-callback="recaptchaSubmit"> <input type="hidden" name="use-recaptcha" value="true"> <?php else: ?> <input type="submit" value="送信する"> <?php endif; ?> ``` ①と同様```?test_recaptcha=0```のパラメータが付いているか否かで 表示するsubmitボタンを切り分けます 上記の例の2行目は下記の様なものになっています ```htmlmixed= <input type="submit" value="送信する" class="g-recaptcha" data-sitekey="【サイトキー】" data-callback="recaptchaSubmit"> ``` * classに```g-recaptcha```を設定 * ```data-sitekey```には登録時に取得した『サイトキー』を設置 * ```data-callback```にはチェックが通った際に実行されるsubmit用の関数を設置 :::danger 【注意点】 jsでsubmitボタンを追加している場合 (サイト訪問時に上記の様なclass名などが設定されているDOMが生成されていない場合) reCaptchaが発火しません。jsでDOMを作成するのではなく、初めからHTMLで生成しておきjsで表示切替を行うような設計に変更してください。 ::: ### ③submit用の関数作成 上記ボタンで指定したコールバック関数を作成します。 引数に渡されている関数```token```はreCaptchaによるチェックを 実効した際に発行されるトークン情報が自動で入ります。 ```php= function recaptchaSubmit(token){ $('form').submit(); } ``` また、上記コールバック関数からsubmitされる際に 自動的に```$_POST['g-recaptcha-response']```へトークンが代入されます。 :::danger 【注意点】 jsでバリデーションチェックを行っている場合、この関数内で呼び出す必要があります。 また、この関数以外でsubmitが行われている場合、その個所を削除する必要があります。 ::: ## バックエンド バックエンド側で、チェックの結果を取得する処理です。 下記URLにリクエストを送信すると、結果が取得できます。 ```php= https://www.google.com/recaptcha/api/siteverify?secret=[シークレットキー]&response=[トークン] ``` レスポンスの例でいうと下記の様なものになります。 ```json= { "success": true, "challenge_ts": "2018-10-01T07:19:10Z", "hostname": "www.test.com" } ``` ```success```が認証結果になります。 :::info 【メモ】 実際にjsで書いたsubmit用の関数に渡されている```token```をconsoleに表示するなどして コピーしておき、上記のURLにシークレットキーと```token```をベタ書きで叩くと レスポンスの内容を確認する事ができます。 ::: ### ①reCaptchaチェック判定結果取得の関数作成 ```php= function checkReCaptcha($token) { if(isset($token)){ $secret_key = 'xxxxxxxxxxxx'; $url = 'https://www.google.com/recaptcha/api/siteverify'; $ch = curl_init(); curl_setopt_array($ch, [ CURLOPT_URL => $url, CURLOPT_RETURNTRANSFER => true, CURLOPT_POST => true, CURLOPT_POSTFIELDS => http_build_query([ 'secret' => $secret_key, 'response' => $token ]), ]); $response = curl_exec($ch); curl_close($ch); return json_decode($response)->success; } return false; } ``` * ```$secret_key```にはサイト登録時に発行された『シークレットキー』を代入してください。 * 引数の```$token```はreCAPTCHAを通してsubmitされた時に、自動的にPOSTされる ```$_POST['g-recaptcha-response']```を渡してください。 * returnではReCAPTCHAのリクエスト結果```success```を返しています。 そもそも```$_POST['g-recaptcha-response']```がない場合はReCAPTCHAを 通っていないのでfalseを返します。 ### ②認証チェック条件分岐の作成 ```php= //reCaptchaチェック if(isset($_POST['use-recaptcha']) && !checkReCaptcha($_POST['g-recaptcha-response'])){ $_SESSION['error_message'] = 'GoogleReCAPTCHA確認中に問題が発生しました。申し訳ありませんが再度送信してください。'; header("Location: [トップページ]"); exit; } ``` ①で作成した関数を呼び出し、falseであれば前ページに戻りtrueであればページ遷移や その他の処理を実行する条件文を適所に追加します。 関数呼び出しの例は下記の通りです。 ```php= checkReCaptcha($_POST['g-recaptcha-response']) ``` また、フロントエンド側の実装②で作業を行っているように GoogleRecaptchaを使用しているフォームのみ ```use-recaptcha```というkeyでPOST行っています。こちらを利用して下記の様な条件文で 処理を分けることで共通ファイルにreCaptchaのバックエンド処理を記載する事ができます。 行っている事としては、reCaptchaを使用しているフォームかつ ①で作成した関数の返り値がfalseの場合はリダイレクトを行い処理を止めています。 上記実装をDB・メール送信処理の前に設置してください。