Movatterモバイル変換


[0]ホーム

URL:


Skip to content
DEV Community
Log in Create account

DEV Community

Cover image for Using google reCaptcha v3 with Perl
Gaurav Rai
Gaurav Rai

Posted on

     

Using google reCaptcha v3 with Perl

In the previous articleUsing google reCaptcha with Perl we talked about reCAPTCHA v2. This time we will take the same example and try to use reCAPTCHA v3 instead.
So lets get started

1. Sign up for an API key pair

We have to register our website at -https://www.google.com/recaptcha/admin/. Provide it with the following parameters

  • Label - Some name for this
  • reCAPTCHA type - select v3.
  • Domains - Your domain name (e.g. myname.com). For local host write "localhost". You can add multiple domain also.Alt Text

After submit you will get "Site Key" and "Secret Key".
Alt Text

We will be using "Site key" on client side and "Secret key" on server side.

2. Adding the widget on client side

We will be using the same example as we have done for v2. For now, I will be putting it on Login page but one advantage of v3 is it can be used on any page and will not interfere with the user. I encourage you to check out the reCAPTCHA v3documentation for more info.
For using the reCAPTCHA in your web page we have to include the js file.

<head><scriptsrc="https://www.google.com/recaptcha/api.js?onload=onloadCallback&render=<Your Site Key>"></script></script></head>
Enter fullscreen modeExit fullscreen mode

We will be adding below code in the web page. You can add these anywhere in your web page.

<inputtype="hidden"id="g-recaptcha-response"name="g-recaptcha-response"><inputtype="hidden"name="action"value="validate_captcha">
Enter fullscreen modeExit fullscreen mode

As mentioned before, v3 doesn't interfere with user, instead it will give a score between 0.0 to 1.0 depending upon the user(Just like probability). 1.0 is very likely a good interaction, 0.0 is very likely a bot. Its up to the site owner to decide what they want to do when they encounter the bot. In v3 the decision making responsibility is with the site owner. Google reCAPTCHA v3 will not block anyone irrespective of user.

Since the decision is up to site owner, you don't want to bind your action on a button click (where a user click on the button then you decide whether it is a bot or not). Instead you will be checking starting from page load and as soon as you came to know it is a bot you can take appropriate action (kicking him out of the page etc.). We will be using little bit of JavaScript for this check.

Again, we will be usingMojo::Template andMojolicious::Plugin::TagHelpers to generate client side code.

<html><head><scriptsrc="https://www.google.com/recaptcha/api.js?onload=onloadCallback&render=<Your Site Key>"></script></head><body>%=th1=>'Login'%if(flash('error')){<h2style="color:red"><%=flash('error')%></h2>%}%=form_forlogin=>(method=>'post')=>begin<label>username:</label><%=text_field'username'%><br/><br /><label>password:</label><%=password_field'password'%><br/><br /><inputtype="hidden"id="g-recaptcha-response"name="g-recaptcha-response"><inputtype="hidden"name="action"value="validate_captcha">%=submit_button'Log in',id=>'submit'%=end<script>functiononloadCallback(){grecaptcha.ready(function(){grecaptcha.execute('<Your Site Key>',{action:'validate_captcha'}).then(function(token){document.getElementById('g-recaptcha-response').value=token;//Createanendpointonyourservertovalidatethetokenandreturnthescorefetch('/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>
Enter fullscreen modeExit fullscreen mode

In summary, we are just creating a normal login form. One noted difference with the v2 version is - here we are calling endpointrecaptchav3-verify on page load only and based on json response, if it is normal user we will just write in console otherwise alert will appear saying its bot.

3. Creating Server side and validating

We will just update the code we have written for v2

#!/usr/bin/env perlusestrict;usewarnings;useMojolicious::Lite;useMojo::UserAgent;subis_valid_captcha{my($c)=@_;# https://docs.mojolicious.org/Mojo/Message#jsonmy$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 botif($out->{success}&&$out->{score}>0.5){return1;}else{# Its a botreturn0;}}else{# Connection to reCAPTCHA failedreturn0;}}# Check for authenticationhelperauth=>sub{my$c=shift;if(($c->param('username')eq'admin')&&($c->param('password')eq'admin')){return1;}else{return0;}};helperua=>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 Routesget'/'=>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';undersub{my$c=shift;return1if($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>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>
Enter fullscreen modeExit fullscreen mode

Save the file and run below command on your terminal -

morbo recaptcha_v2_verification.pl
Enter fullscreen modeExit fullscreen mode

One noticeable difference is addition ofrecaptchav3-verify route. We are just verifying the captcha by reading the post params and doing a post request on google api and checking the response for success. The response is a JSON object -

{"success":true|false,      // whether this request was a valid reCAPTCHA tokenforyour site"score": number             // the scoreforthis request(0.0 - 1.0)"action": string            // the action nameforthis request(important to verify)"challenge_ts": timestamp,  // timestamp of the challenge load(ISO format yyyy-MM-dd'T'HH:mm:ssZZ)"hostname": string,         // thehostnameof the site where the reCAPTCHA was solved"error-codes":[...]        // optional}
Enter fullscreen modeExit fullscreen mode

We are checking the score. If it is less than0.5 we are considering it as bot. We are using the threshold as 0.5 here but you are free to choose depending upon whether you want to be strict or lenient.
From v3doc

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

After that we are returning a json response to client side. We are usingMojo::JSON to convert the value into booleantrue orfalse.
Go to browser and hit "http://localhost:3000". You can see your login page with reCAPTCHA widget on the bottom right.
Alt Text
For a successful verification you can see thehome page
Alt Text
In case of bot access you can see an alert
Alt Text
Here I am just alerting when there is a bot, but you can choose what action you wan to do.
There is high chance where you will not see the bot alert initially even though a bot will access your page. But some frequent access in some time, v3 will learn and start alerting about it.
You can also look at youradmin console over a time and look at overall traffic and suspicious requests.
Here is one such example -
Alt Text
The complete example is also available atGithub
I hope this is helpful to you.

Perl onion logo taken fromhere
Mojolicious logo taken fromhere
reCAPTCHA logo taken fromhere

Top comments(0)

Subscribe
pic
Create template

Templates let you quickly answer FAQs or store snippets for re-use.

Dismiss

Are you sure you want to hide this comment? It will become hidden in your post, but will still be visible via the comment'spermalink.

For further actions, you may consider blocking this person and/orreporting abuse

  • Location
    India
  • Joined

More fromGaurav Rai

DEV Community

We're a place where coders share, stay up-to-date and grow their careers.

Log in Create account

[8]ページ先頭

©2009-2025 Movatter.jp