【GCP】reCAPTCHAの設定方法

2022年11月23日

reCAPTCHA は Google が提供する 認証システムです。v2は画像を選択して認証するシステムです。「自転車を選んでください」などはreCAPTCHA v2の認証システムです。v3はスコアによるbot判定をします。ユーザーが認証操作から開放され負担が減る一方、サイト運営側でbot判定した場合のふるまいの実装などが必要になります。

今回はv3の実装の忘備録となります。

キーの取得

reCAPTCHA にサイトを登録する  際に、reCAPTCHA タイプで v3 を選択してサイトキーとサイトシークレットを取得します。

クライアント側の実装

<script src="https://www.google.com/recaptcha/api.js?render=サイトキー"></script>
<script>
var rc_form = document.getElementById('rc_form');
//フォーム要素にイベントハンドラを設定
rc_form.onsubmit = function(event) {
  //デフォルトの動作(送信)を停止
  event.preventDefault();  
  //トークンを取得
  grecaptcha.ready(function() {
    grecaptcha.execute('サイトキー', {action: 'アクション名'}).then(function(token) {
      var token_input = document.createElement('input'); //input 要素を生成
      token_input.type = 'hidden';
      token_input.name = 'g-recaptcha-response';
      token_input.value = token; //トークンを値に設定
      rc_form.appendChild(token_input);
      var action_input = document.createElement('input'); //input 要素を生成
      action_input.type = 'hidden';
      action_input.name = 'action';
      action_input.value = 'アクション名';  //アクション名を値に設定
      rc_form.appendChild(action_input); 
      rc_form.submit();  //フォームを送信
    });
  });
}
</script>

PHPを使用した検証

取得したサイトキーとシークレットキーを記述します。

<?php
// reCAPTCHA v3 サイトキー
define('V3_SITEKEY', 'サイトキー');
// reCAPTCHA v3 シークレットキー
define('V3_SECRETKEY', 'シークレットキー');
<?php
// サイトキーとシークレットキーを記述したファイルの読み込み
require 'php/recaptcha_vars.inc';
// reCAPTCHA サイトキー
$siteKey = V3_SITEKEY;
// reCAPTCHA シークレットキー
$secretKey = V3_SECRETKEY;
//reCAPTCHA トークン
$token = isset( $_POST[ 'g-recaptcha-response' ] ) ? $_POST[ 'g-recaptcha-response' ] : NULL;
//reCAPTCHA アクション名 
$action = isset( $_POST[ 'action' ] ) ? $_POST[ 'action' ] : NULL;
 
$result_status = ''; // 結果を表示する文字列を初期化

// トークンとアクション名が取得の可否
if ( $token && $action) {
 
  //cURL セッションを初期化(API のレスポンスの取得)
  $ch = curl_init();

  //URL の指定
  curl_setopt($ch, CURLOPT_URL,"https://www.google.com/recaptcha/api/siteverify");
  //HTTP POST メソッドを使う
  curl_setopt($ch, CURLOPT_POST, true );
  //API パラメータの指定
  curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query(array(
    'secret' => $secretKey, 
    'response' => $token
  )));
  //curl_execの返り値を文字列にする
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  //転送を実行してレスポンスを $api_response に格納
  $api_response = curl_exec($ch);
  //セッションを終了
  curl_close($ch);
  
  //レスポンスの $json(JSON形式)をデコード
  $result = json_decode( $api_response );
  
  //判定
  if ( $result->success && $result->action === $action && $result->score >= 0.5) {
    //success が true でアクション名が一致し、スコアが 0.5 以上の場合は合格
    $result_status = '合格: $result->score : ' . $result->score;
    // 合格した場合の処理(結果を変数に入れて、その変数を使って処理を分岐)
  } else {
    // 上記以外の場合は 不合格
    $result_status = '不合格';

  }

}
?>

reCAPTCHAの判定結果を使用して動作を分岐する。

<?php if ($result_status === "不合格" || $result_status === Null) : ?>
	<div>
		<h2>認証されませんでした</h2>
		<p>
			再度送信するかブラウザーの再起動をしてください<br>
		</p>
	</div>
<?php
	return;
endif; ?>



GCP,Javascript,PHP

Posted by Next-k