を使用してGoogle Recaptcha


前の記事ではrecaptcha v 2について話しました.今回は同じ例を取り、代わりにrecaptcha v 3を使用します.
だから始める

APIキーペアにサインアップする


我々のウェブサイトを登録する必要がありますhttps://www.google.com/recaptcha/admin/ . 次のパラメータを指定します
  • ラベル-このためのいくつかの名前
  • recaptcha - V 3を選択します.
  • ドメイン-ドメイン名(例: myname . com ).ローカルホストでは"localhost "を書き込みます.また、複数のドメインを追加することができます.

  • 後に“サイトキー”と“秘密キー”を取得します.

    クライアント側で「サイトキー」とサーバー側の「秘密鍵」を使います.

    2 .クライアント側でウィジェットを追加する


    私たちはv 2のために行ったのと同じ例を使います.今のところ、私はログインページにそれを置くでしょう、しかし、V 3の1つの利点はどんなページででも使われることができて、ユーザーと干渉しないことです.私はあなたがrecaptcha v 3をチェックアウトすることをお勧めしますdocumentation を参照してください.
    あなたのウェブページのRecaptchaを使用するには、JSファイルを含める必要があります.
    <head>
        <script src="https://www.google.com/recaptcha/api.js?onload=onloadCallback&render=<Your Site Key>"></script></script>
    </head>
    
    我々は、Webページにコードの下に追加されます.あなたはどこでもあなたのウェブページにこれらを加えることができます.
        <input type="hidden" id="g-recaptcha-response" name="g-recaptcha-response">
        <input type="hidden" name="action" value="validate_captcha">
    
    前に述べたように、V 3はユーザーと干渉しません.その代わりに、それはユーザーに応じて0.0から1.0までのスコアを与えます(確率と同じように).1.0は非常に良い相互作用、0.0は非常に可能性が高いボットです.そのサイトの所有者は、彼らがボットに遭遇するときに何をしたいかを決定します.v 3において、意思決定責任はサイト所有者とあります.Google recaptcha v 3は、ユーザーに関係なく、誰もブロックしません.
    決定はサイトの所有者までですので、あなたはボタンクリック(あなたのボタンをクリックした後、それがボットであるかどうかを決める)にあなたの行動をバインドする必要はありません.代わりに、ページの負荷から起動し、すぐにあなたが適切なアクション(ページなどから彼を蹴ることができますボット)知っているようになった.このチェックのためにJavaScriptを少し使用します.
    再び、我々は使用されますMojo::Template and Mojolicious::Plugin::TagHelpers クライアント側のコードを生成します.
    <html>
        <head>
            <script src="https://www.google.com/recaptcha/api.js?onload=onloadCallback&render=<Your Site Key>"></script>
        </head>
        <body>
            %= t h1 => 'Login'
            % if (flash('error')) {
                <h2 style="color:red"><%= flash('error') %></h2>
            % }
            %= form_for login => (method => 'post') => begin
                <label>username:</label> <%= text_field 'username' %>
            <br /><br />
                <label>password:</label> <%= password_field 'password' %>
            <br /><br />
                <input type="hidden" id="g-recaptcha-response" name="g-recaptcha-response">
                <input type="hidden" name="action" value="validate_captcha">
            %= submit_button 'Log in', id => 'submit'
            %= end
            <script>
                function onloadCallback() {
                    grecaptcha.ready(function() {
                        grecaptcha.execute('<Your Site Key>', {action:'validate_captcha'})
                        .then(function(token) {
                            document.getElementById('g-recaptcha-response').value = token;
                            // Create an endpoint on your server to validate the token and return the score
                            fetch('/recaptchav3-verify', {
                                method: 'POST',
                                headers: {
                                    'Content-Type': 'application/json',
                                },
                                body: JSON.stringify({'token': token})
                            })
                            .then(response => response.json())
                            .then(data => {
                                if (data.error === true) {
                                    alert(data.description + " Bot found.");
                                }
                                else {
                                    console.log('reCaptcha verification : success');
                                }
                            })
                            .catch((error) => {
                                console.error('Error:', error);
                            });
                        });
                    });
                }
            </script>
        </body>
    </html>
    
    要約すると、通常のログインフォームを作成しています.V 2バージョンとの1つの注意点の違いはrecaptchav3-verify ページロードだけで、JSON応答に基づいて、それが通常のユーザーであるならば、我々はちょうどコンソールでそれ以外の警告を書くでしょう.

    サーバー側の作成と妥当性検査


    v 2用に書かれたコードを更新します
    #!/usr/bin/env perl
    
    use strict;
    use warnings;
    use Mojolicious::Lite;
    use Mojo::UserAgent;
    
    sub is_valid_captcha {
        my ($c) = @_;
    
        # https://docs.mojolicious.org/Mojo/Message#json
        my $post_params = $c->req->json;
        my $token       = $post_params->{token};
        my $captcha_url = 'https://www.google.com/recaptcha/api/siteverify';
        my $response
            = $c->ua->post(
            $captcha_url => form => {response => $token, secret => $ENV{'CAPTCHA_V3_SECRET_KEY'}})
            ->result;
        if ($response->is_success()) {
            my $out = $response->json;
    
            # reCAPTCHA v3 returns a score -> 1.0 is very likely a good interaction, 0.0 is very likely a bot
            if ($out->{success} && $out->{score} > 0.5) {
                return 1;
            }
            else {
                # Its a bot
                return 0;
            }
        }
        else {
            # Connection to reCAPTCHA failed
            return 0;
        }
    }
    
    # Check for authentication
    helper auth => sub {
        my $c = shift;
    
        if (($c->param('username') eq 'admin') && ($c->param('password') eq 'admin')) {
            return 1;
        }
        else {
            return 0;
        }
    };
    
    helper ua => sub {
        my $ua = Mojo::UserAgent->new;
        $ua->transactor->name('Mozilla/5.0 (Windows NT 6.1; WOW64; rv:77.0) Gecko/20190101 Firefox/77.0');
        return $ua;
    };
    
    # Different Routes
    get '/' => sub { 
        my $c = shift;
        $c->render;
    } => 'index';
    
    post '/login' => sub {
        my $c = shift;
        if ($c->auth) {
            $c->session(auth => 1);
            $c->flash(username => $c->param('username'));
            return $c->redirect_to('home');
        }
        $c->flash('error' => 'Wrong login/password');
        $c->redirect_to('index');
    } => 'login';
    
    post '/recaptchav3-verify' => sub {
        my $c = shift;
        if (is_valid_captcha($c)) {
            return $c->render(
                json => {
                          error => Mojo::JSON->false
                        }
            );
        }
        else {
            return $c->render(
                json => {
                          error => Mojo::JSON->true,
                          description => 'Captcha verification failed.'
                        }
            );
        }
    };
    
    get '/logout' => sub {
        my $c = shift;
        delete $c->session->{auth};
        $c->redirect_to('index');
    } => 'logout';
    
    under sub {
        my $c = shift;
        return 1 if ($c->session('auth') // '') eq '1';
    
        $c->render('denied');
    };
    
    get '/home' => sub {
        my $c = shift;
        $c->render();
    } => 'home';
    
    app->start;
    
    __DATA__
    
    @@ index.html.ep
    <html>
        <head>
            <script src="https://www.google.com/recaptcha/api.js?onload=onloadCallback&render=<Your Site Key>"></script>
        </head>
        <body>
            ... as in Step 2
        </body>
    </html>
    
    @@ home.html.ep
    %= t h1 => 'Home Page'
    <h2 style="color:green">Hello <%= flash('username') %></h2>
    <a href="<%= url_for('logout') %>">Logout</a>
    
    @@ denied.html.ep
    %= t h2 => 'Access Denied'
    <a href="<%= url_for('index') %>">Login</a>
    
    ファイルを保存し、コマンドを以下のコマンドで実行します.
    morbo recaptcha_v2_verification.pl
    
    つの顕著な違いはrecaptchav3-verify ルート私たちは、ちょうどポスト・パームを読んで、Google APIでポストリクエストをして、成功のためにレスポンスをチェックすることによって、captchaを確かめています.レスポンスはJSONオブジェクトです.
    {
      "success": true|false,      // whether this request was a valid reCAPTCHA token for your site
      "score": number             // the score for this request (0.0 - 1.0)
      "action": string            // the action name for this request (important to verify)
      "challenge_ts": timestamp,  // timestamp of the challenge load (ISO format yyyy-MM-dd'T'HH:mm:ssZZ)
      "hostname": string,         // the hostname of the site where the reCAPTCHA was solved
      "error-codes": [...]        // optional
    }
    
    我々はスコアをチェックしている.それが0.5未満であるならば、我々はそれをBOTと考えています.私たちは、しきい値を0.5として使用していますが、厳しいか寛大になりたいかどうかに応じて選択する自由です.
    V 3からdoc

    reCAPTCHA learns by seeing real traffic on your site. For this reason, scores in a staging environment or soon after implementing may differ from production. As reCAPTCHA v3 doesn't ever interrupt the user flow, you can first run reCAPTCHA without taking action and then decide on thresholds by looking at your traffic in the admin console


    その後、クライアント側にJSONレスポンスを返します.私たちはMojo::JSON 値をbooleanに変換するにはtrue or false .
    ブラウザに移動してhttp://localhost:3000 あなたは下の右側にウィジェットをRecaptchaであなたのログインページを見ることができます.

    成功した検証のためにhome ページ

    ボットアクセスの場合は、アラートを見ることができます

    ここでは、ちょうどボットがあるとき、私は警告しています、しかし、あなたはあなたがするどんな行動を選ぶことができます.
    ボットがあなたのページにアクセスしますが、ボットの警告を最初に表示されません高いチャンスがあります.しかし、いくつかの時間でいくつかの頻繁にアクセス、V 3を学び、それについて警告を開始します.
    また、あなたを見ることができますadmin console 時間をかけて、全体的なトラフィックと疑わしい要求を見てください.
    以下にその例を示します.

    完全な例はまたGithub
    これがあなたに役立つことを願っています.
    Perlオニオンロゴhere
    からのMojoliciousロゴhere
    から取り戻されるロゴを取り除いてくださいhere