phpでreCAPTCHA v3を導入する(検証用サンプルコード付き)

この記事について

環境PHP + reCAPTCHA v3
目的フォームにreCAPTCHA v3を導入してbot対策する
結果検証用サンプル2種類で動作確認できた

事前にreCAPTCHA管理コンソール(https://www.google.com/recaptcha/admin)でサイトを登録して、sitekeyとsecretkeyを取得しておく。
reCAPTCHA v3はチャレンジ(画像選択など)が出ない代わりに、リクエストごとに0.0〜1.0のスコアが返る。スコアのしきい値(このコードでは0.5)で合否を判定する。

テスト用ソースコード1(cURLでsiteverify + アクション名検証)

<?php

$sitekey = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';        // reCAPTCHA v3 sitekey

$secretkey = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';			// reCAPTCHA v3 secretkey

//reCAPTCHA token

$token = isset( $_POST[ 'try_recaptcha-response' ] ) ? $_POST[ 'try_recaptcha-response' ] : NULL;

//reCAPTCHA action

$action = isset( $_POST[ 'action' ] ) ? $_POST[ 'action' ] : NULL;



$Ret = ''; // result strings



if ($token && $action) {//token&action取得時。nullなら実行されない

  //get API Response

  $ch = curl_init();  //cURL session initialize

  curl_setopt($ch, CURLOPT_URL,"https://www.google.com/recaptcha/api/siteverify");

  curl_setopt($ch, CURLOPT_POST, true );

  curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query(array('secret' => $secretkey, 'response' => $token )));

  curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

  $api_response = curl_exec($ch);

  curl_close($ch);

  

  //API Response decode(JSON形式)

  $result = json_decode( $api_response );

  //$result->success = true(成功) / $result->action == $action(アクション名一致) / score 0.5以上はOK

  if ( $result->success && $result->action === $action && $result->score >= 0.5) { //score 0.5以上はOK

    $Ret = '合格: $result->score : ' . $result->score . $api_response;

    // この場合に成功時の処理を入れれば良い。

  } else {

    $Ret = '不合格: $result->score : ' . $result->score . $api_response;

    // エラー処理を実行

  }

}

?>

<!DOCTYPE html>

<html lang="ja">

<head>

<title>Google reCAPTCHA v3検証</title>

</head>

<body>

  <h1>PHPを使っての検証</h1>

  <form id="try_form" method="post">

    <button type="submit">送信</button>

  </form>

  <div>

    <p>[検証結果]</p>

    <p><?php echo $Ret; ?></p>

  </div>

<script src="https://www.google.com/recaptcha/api.js?render=<?php echo $sitekey; ?>"></script>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>

<script>

jQuery(function($){

  jQuery('#try_form').submit(function(event) {

    event.preventDefault();

    var action_name = 'contact'; //アクション名 

    grecaptcha.ready(function() {

      grecaptcha.execute('<?php echo $sitekey; ?>', { action: action_name }).then(function(token) {

        jQuery('#try_form').prepend('<input type="hidden" name="try_recaptcha-response" value="' + token + '">');

        jQuery('#try_form').prepend('<input type="hidden" name="action" value="' + action_name + '">');

        jQuery('#try_form').unbind('submit').submit();

      });

    });

  });

})

</script>

</body>

</html>

テスト用ソースコード2(file_get_contentsの簡易版)

<?php

// サイトキーを入力

$key = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';

// シークレット キーを入力

$secretKey = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';

if (isset($_POST['name']) && isset($_POST['password'])) 

{

  $Response = file_get_contents('https://www.google.com/recaptcha/api/siteverify?secret='.$secretKey.'&response='.$_POST['g-recaptcha-response']);

  $result = json_decode($Response);

    $score = $result->score;

  if ($result->success) 

  {

    $message = 'success';

    $status = 'success';



  } 

  else 

  {

    $message = $result->{'error-codes'}[0];

    $status = 'danger';

  }

}

?>

<!DOCTYPE html>

<html lang="ja">

<head>

  <meta charset="UTF-8">

  <title>Title</title>

  <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">

  <script src="https://www.google.com/recaptcha/api.js?render=<?php echo $key ?>"></script>

  <script>

  grecaptcha.ready(function() {

    grecaptcha.execute('<?php echo $key ?>', {action: 'login'}).then(function(token) {

    var reCAPTCHA = document.getElementById('recaptcha');

         reCAPTCHA.value = token;

    });

  });

  </script>

</head>

<body>

  <div class="content">

    <div class="col-sm-5">

      <?php echo isset($message) ? sprintf('<div class="alert alert-%s" role="alert">%s</div>',$status,$message):'' ?>

      <?php echo "スコア" . $score; ?>

      <form class="form" method="post">

        <div class="form-group">

      <label for="formGroupExampleInput">name</label>

      <input type="text" class="form-control" id="formGroupExampleInput" placeholder="name input" name="name">

    </div>

    <div class="form-group">

      <label for="formGroupExampleInput2">password</label>

      <input type="password" class="form-control" id="formGroupExampleInput2" placeholder="password input" name="password">

    </div>

    <input type="hidden" name="g-recaptcha-response" id="recaptcha" />

    <button type="submit" class="btn btn-primary">送信</button>

      </form>

    </div>

  </div>    

</body>

</html>

参考

https://www.kabanoki.net/4553/
タイトルとURLをコピーしました