2424
2525sub is_valid_captcha {
2626 my ($c ) = @_ ;
27- my $ua = Mojo::UserAgent-> new;
28- my $param = $c -> param(' g-recaptcha-response' );
27+
28+ # https://docs.mojolicious.org/Mojo/Message#json
29+ my $post_params = $c -> req-> json;
30+ my $token = $post_params -> {token };
2931 my $captcha_url = ' https://www.google.com/recaptcha/api/siteverify' ;
3032 my $response
31- = $ua -> post(
32- $captcha_url => form => {response => $param , secret => $ENV {' CAPTCHA_V3_SECRET_KEY' }})
33+ = $c -> ua-> post(
34+ $captcha_url => form => {response => $token , secret => $ENV {' CAPTCHA_V3_SECRET_KEY' }})
3335 -> result;
3436 if ($response -> is_success()) {
3537 my $out = $response -> json;
38+
3639 # reCAPTCHA v3 returns a score -> 1.0 is very likely a good interaction, 0.0 is very likely a bot
3740 if ($out -> {success } && $out -> {score } > 0.5) {
3841 return 1;
@@ -58,12 +61,10 @@ sub is_valid_captcha {
5861 return 0;
5962};
6063
61- helper verify_captcha => sub {
62- my $c = shift ;
63- if (is_valid_captcha($c )) {
64- return 1;
65- }
66- return 0;
64+ helper ua => sub {
65+ my $ua = Mojo::UserAgent-> new;
66+ $ua -> transactor-> name(' Mozilla/5.0 (Windows NT 6.1; WOW64; rv:77.0) Gecko/20190101 Firefox/77.0' );
67+ return $ua ;
6768};
6869
6970# Different Routes
@@ -72,20 +73,25 @@ sub is_valid_captcha {
7273post ' /login' => sub {
7374 my $c = shift ;
7475 if ($c -> auth) {
75- if ($c -> verify_captcha) {
76- $c -> session(auth => 1);
77- $c -> flash(username => $c -> param(' username' ));
78- return $c -> redirect_to(' home' );
79- }
80- else {
81- $c -> flash(' error' => ' Captcha verification failed' );
82- $c -> redirect_to(' index' );
83- }
76+ $c -> session(auth => 1);
77+ $c -> flash(username => $c -> param(' username' ));
78+ return $c -> redirect_to(' home' );
8479 }
8580 $c -> flash(' error' => ' Wrong login/password' );
8681 $c -> redirect_to(' index' );
8782} => ' login' ;
8883
84+ post ' recaptchav3-verify' => sub {
85+ my $c = shift ;
86+ if (is_valid_captcha($c )) {
87+ return $c -> render(json => {error => Mojo::JSON-> false});
88+ }
89+ else {
90+ return $c -> render(
91+ json => {error => Mojo::JSON-> true, description => ' Captcha verification failed.' });
92+ }
93+ };
94+
8995get ' /logout' => sub {
9096 my $c = shift ;
9197 delete $c -> session-> {auth };
@@ -115,7 +121,7 @@ sub is_valid_captcha {
115121 <head>
116122 <link href="https://fonts.googleapis.com/css?family=Nunito:200,600" rel="stylesheet">
117123 <script src="https://code.jquery.com/jquery-3.5.1.min.js" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>
118- <script src="https://www.google.com/recaptcha/api.js?onload=onloadCallback&render=Your Site Key"></script>
124+ <script src="https://www.google.com/recaptcha/api.js?onload=onloadCallback&render=< Your Site Key> "></script>
119125 </head>
120126 <body>
121127 %= t h1 => 'Login'
@@ -131,13 +137,34 @@ sub is_valid_captcha {
131137 <br /><br />
132138 <input type="hidden" id="g-recaptcha-response" name="g-recaptcha-response">
133139 <input type="hidden" name="action" value="validate_captcha">
134- %= submit_button 'Log in'
140+ %= submit_button 'Log in', id => 'submit'
135141 %= end
136142 <script>
137143 function onloadCallback() {
138144 grecaptcha.ready(function() {
139- grecaptcha.execute('Your Site Key', {action:'validate_captcha'}).then(function(token) {
145+ grecaptcha.execute('<Your Site Key>', {action:'validate_captcha'})
146+ .then(function(token) {
140147 document.getElementById('g-recaptcha-response').value = token;
148+ // Create an endpoint on your server to validate the token and return the score
149+ fetch('/recaptchav3-verify', {
150+ method: 'POST',
151+ headers: {
152+ 'Content-Type': 'application/json',
153+ },
154+ body: JSON.stringify({'token': token})
155+ })
156+ .then(response => response.json())
157+ .then(data => {
158+ if (data.error === true) {
159+ alert(data.description + " Bot found.");
160+ }
161+ else {
162+ console.log('reCaptcha verification : success');
163+ }
164+ })
165+ .catch((error) => {
166+ console.error('Error:', error);
167+ });
141168 });
142169 });
143170 }
@@ -155,4 +182,3 @@ sub is_valid_captcha {
155182@@ denied.html.ep
156183%= t h2 => 'Access Denied'
157184<a href="<%= url_for('index') %>">Login</a>
158-
0 commit comments