26
16

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

reCAPTCHA V3導入の問題点

Last updated at Posted at 2019-05-16

結構ハマるなこれ。

ヾ(・ω<)ノ" 三三三● ⅱⅲ コロコロ♪


------------------- ↓ 余談はここから ↓-------------------
スパム対策にGoogle謹製のreCAPTCHAを導入することは多いと思う。
I'm not a robot でパズルやらされる例のアレだが、
Version3.0ではあのパズルがなくなって、
AIで判別するようになるらしい。
実装はV2とほぼ一緒で簡単に終わったなと思った。

ところが、数日後、

投稿者数が減ったような気がする

という連絡が。

(゚-゚) こりゃあかんやつやも。

こちらとしてはGoogleの実装例そのまま載せたのだが、
エラーを解析した結果、
timeout-or-duplicate というエラーばかりだった。

マニュアルには

timeout-or-duplicate
The response is no longer valid: either is too old or has been used previously. 

https://developers.google.com/recaptcha/docs/verify
と記載されているが、
このtoo oldとは何時間のことなのか。
実際に測ってみたら。5分だった。

_人人人人人人人人_
> Too Old: 5分 <
 ̄Y^Y^Y^Y^Y^Y^Y^Y^ ̄

有効期限を延ばす手段は管理画面とかにもない。
Googleさん、そりゃねーよ。
さて、困った。これで実装方法を大幅に変えなきゃならん。
方法は3つ。

  1. タイマーでtokenを再発行
  2. サブミットの直前で発行
  3. timeout-or-duplicateを許容する

(。_。) さて。。。


------------------- ↓ 本題はここから ↓-------------------

タイマーでtokenを再発行

コードはこんな感じになるだろうか

grecaptcha.ready(function() {
  grecaptcha.execute('reCAPTCHA_site_key', {action: 'user/register'});
  var ticker = setInterval(function(){
    try{
      grecaptcha.reset();
      clearInterval(ticker);
    } catch(e) {}
  },250);
}

一定時間が経過した時点でresetを実行する。
これでキーが再発行される(らしい)
setIntervalかsetTimeoutかはお好みで。

サブミットの直前で発行

コードはこんな感じになるだろうか
(Jquery記述で申し訳ない)

  grecaptcha.ready(function() {
    $('.recaptcha')
      .on('click', function () {
        grecaptcha
         .execute('reCAPTCHA_site_key', {action:'article/edit'})
         .then(function(token) {
           $('form:first').submit();
         });
      });
  });

サブミットボタン(type=button)を押したときに、
Googleからキーを発行して貰い、
それが完了したらsubmitを実行する流れ。

これであればタイムアウトが5分でも問題は起こらない。

timeout-or-duplicateを許容する

Googleサーバーにverify掛け、
bot判定(Success:false)されたときに結果JSONは以下のような感じになる。

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

このerror-codesを判別してtimeout-or-duplicateの時はそのまま受け付ける。


------------------- ↓ 後書はここから ↓-------------------

実際採用したのは3番目。
timeout-or-duplicateを許容するである。

タイマーはなるべく避けたかったし、
JSゴリゴリでテスト満載も避けたかったのがその理由。

参考記事:
https://stackoverflow.com/questions/48133487/getting-invisible-recaptcha-to-trigger-on-page-load

26
16
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
26
16

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?