Help us understand the problem. What is going on with this article?

Google reCAPTCHA v3をGoogle Apps Scriptで実験してみた

思うところがあってreCAPTCHA v3を触ってみたく、試してみました。
バックエンドの環境準備も面倒だったので、バックエンドはGASでやってみました。
JavaScriptとHTMLしかサンプルに登場しないのも良し。

Google reCAPTCHA v3

いわゆる 「ロボットではありません」 なんですが、それはv2まで。
v3はそれが要らなくなったらしい。

今回、ターゲットになるフォーム

僕の実験サイトなので好きに触ってみてください。

https://pokosho.com/a/recaptcha/

よくあるお問い合わせフォームになります。
form名もcontactで悪いbotさんに拾ってもらえそう?

key, secretの発行

https://www.google.com/recaptcha/admin/create
ここからkeyとsecretを発行します。

keyはフロントエンドに埋め込むので誰に見られても良いものですがsecretはその名の通り秘密にすべきもので、バックエンドで使います。

フロントエンド

Googleにkeyを渡し、tokenを受け取り、バックエンドにわたす必要があります。

<input type="hidden" name="recaptcha" id="recaptcha" />

hiddenパラメータを用意しました。

<script src="https://www.google.com/recaptcha/api.js?render=[key]"></script>

recaptchaのスクリプトにkeyを渡して読み込みます。
[key] には取得したkeyを入れてくださいね。

grecaptcha.ready(function() {
  grecaptcha.execute('[key]', {action: 'homepage'}).then(function(token) {
    var recaptcha = document.getElementById('recaptcha');
    recaptcha.value = token;
  });
});

[key] には取得したkeyを入れてくださいね。
grecaptcha.executeを呼ぶとtokenが得られますので、上記のhiddenパラメータに入力しておきます。
actionはformのactionではなく、Googleの指定するactionで、 homepage, login, social, e-commerce のいずれかを指定します。
名前からある程度わかりますが、詳しくはドキュメントを参照ください。

バックエンド(GAS)

雑にもほどがありますが、受け取ったパラメータをspreadsheetにぶちこみます。

function doPost(e) {
  var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
  var values = [];
  // TODO: パラメータの順番が保証されているとは限らないのでこんなことをしてはいけません
  for (key in e.parameters) {
    values.push(e.parameters[key][0]);
  }

  var recaptchaRes = validateRequest(e);
  // TODO: 本当はここで recaptchaRes.success ではないものを捨てる
  // 今回は全部みたいので乱暴にspreadsheetに入れています。
  values.push(recaptchaRes);
  sheet.appendRow(values);
}

function validateRequest(e) {
  var payload = {
    "secret": "[secret]",
    "response": e.parameters["recaptcha"][0],
  };
  var options = {
    "method" : "post",
    "payload" : payload
  };

  var res = UrlFetchApp.fetch("https://www.google.com/recaptcha/api/siteverify", options);
  return res;
}

[secret] はsecretをいれてください。外部にもれないように注意しましょう。

試してみた

image.png

正常系

{
  "success": true,
  "challenge_ts": "2019-08-16T14:21:18Z",
  "hostname": "pokosho.com",
  "score": 0.9,
  "action": "homepage"
}

高いスコアです。

JSでクリックしてみる

Chrome Developer Toolを立ち上げ、consoleからJSでクリックしてみる。

document.getElementById("submit").click();
{
  "success": true,
  "challenge_ts": "2019-08-16T14:21:40Z",
  "hostname": "pokosho.com",
  "score": 0.9,
  "action": "homepage"
}

なんだと?
v2の「私はロボットではありません」に対してこれをやると怒られたのですが…!
ブックマークレットとかも使えそうですね。

同じリクエストを飛ばしてみる

Chrome Developer ToolからCopy as cURLする。

image.png

{
  "success": false,
  "error-codes": [
    "timeout-or-duplicate"
  ]
}

おお〜。

headless chrome

環境構築が面倒なので…。誰か編集リクエストください…。

まとめ

  • 「私はロボットではありません」の印象が強すぎて「UXを損ねるのでは?」という懸念が挙がるがそんなことはない!
  • JS読み込んで終わり、というわけにはいかない。botかどうかの判定はバックエンドで行う。
  • Googleからドメインを指定してkeyとsecretを発行する。
  • keyはフロントエンドからGoogleに渡す。するとtokenが得られる。
  • tokenをバックエンドに渡す。
  • バックエンドはtokenとsecretをGoogleに渡す。すると判定結果が得られる。
  • 判定結果はbool値の success のパラメータ見れば良い。
  • ReactやVueでやる場合、ライブラリを使うのが良さそうですね。
  • 登場人物は多い。駆け出しエンジニアには難しいかも知れない。
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした