Google reCAPTCHA v3 の動作サンプルを作ってみた

完成品

reCAPTCHAv3

補足

GoogleAppsScriptのフェッチ回数制限があるため、大量アクセスはご遠慮ください。10回、20回程度であれば問題はありません。

動作概要

  1. Webページを表示する
    • WebページにreCAPTCHAv3のスクリプトを読み込む
    • 確認ボタンを無効とする
  2. WebページのreCAPTCHAスクリプトを実行する
    • スクリプトがreCAPTCHAサーバと通信する
      • reCAPTCHAサーバからトークンを取得する
    • 確認ボタンを有効とする
  3. 確認ボタンをクリックする
    • GoogleAppsScriptのウェブアプリケーションにアクセスする
      • トークンを渡す
  4. GoogleAppsScriptがreCAPTCHAサーバにアクセスする
    • 認証の結果を取得する
  5. GoogleAppsScriptが認証の結果をWebページに戻す
  6. Webページが認証の結果を表示する

reCAPTCHAのAPIキーの取得

上記のリンクからAPIキー(サイトキーとシークレットキー)を取得できます。

ソース

<script src='https://www.google.com/recaptcha/api.js?render=サイトキー'></script>
<script>
var reCAPTCHA_token;
grecaptcha.ready(function() {
  grecaptcha.execute('サイトキー', {action: 'testAction'}).then(function(token) {
    reCAPTCHA_token = token;
    document.querySelector('.app-form-button').disabled = false;
  });
});
</script>

<script>
function onReCaptchaButton() {
  document.querySelector('.app-form-button').disabled = true;

  var xhr= new XMLHttpRequest();
  xhr.open("post", 'GASウェブアプリケーションURL', true);
  xhr.onload = function (event) {
    if (xhr.readyState === 4) {
      if (xhr.status === 200) {
        console.log(xhr.statusText);
        console.log(xhr.responseText);
        document.querySelector('.app-form-result').value = xhr.responseText;
      } else {
        console.log(xhr.statusText);
      }
    }
  };
  xhr.onerror = function (event) {
    //console.log(event.type);
  };
  xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
  xhr.send('token='+reCAPTCHA_token );

}
</script>

<form name='recaptcha-form' >
  <div style="width:100%;margin-top:1em;text-align:center;">
    <button class='app-form-button' type='button' onclick="onReCaptchaButton();" disabled style="width:50%;min-windth:4em;">確認</button>
  </div>
  <br/>
  <textarea class="app-form-result" name="description" rows="3" placeholder='結果出力欄' style="width:100%;"></textarea>
</form>

function doPost(e) {
  var json = {};

  // reCAPTCHA認証確認
  try {
    var url = 'https://www.google.com/recaptcha/api/siteverify';
    var option = {
      method: "POST",
      payload: {
        secret: 'シークレットキー',
        response: e.parameter.token
      }
    };
    var response = UrlFetchApp.fetch(url, option);
    if (response != null) {
      json = JSON.parse(response.getContentText('UTF-8'));
    }
  } catch (e) {}

  return ContentService.createTextOutput(JSON.stringify(json))
  .setMimeType(ContentService.MimeType.JSON);
}