24
24
25
25
sub is_valid_captcha {
26
26
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 };
29
31
my $captcha_url = ' https://www.google.com/recaptcha/api/siteverify' ;
30
32
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' }})
33
35
-> result;
34
36
if ($response -> is_success()) {
35
37
my $out = $response -> json;
38
+
36
39
# reCAPTCHA v3 returns a score -> 1.0 is very likely a good interaction, 0.0 is very likely a bot
37
40
if ($out -> {success } && $out -> {score } > 0.5) {
38
41
return 1;
@@ -58,12 +61,10 @@ sub is_valid_captcha {
58
61
return 0;
59
62
};
60
63
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 ;
67
68
};
68
69
69
70
# Different Routes
@@ -72,20 +73,25 @@ sub is_valid_captcha {
72
73
post ' /login' => sub {
73
74
my $c = shift ;
74
75
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' );
84
79
}
85
80
$c -> flash(' error' => ' Wrong login/password' );
86
81
$c -> redirect_to(' index' );
87
82
} => ' login' ;
88
83
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
+
89
95
get ' /logout' => sub {
90
96
my $c = shift ;
91
97
delete $c -> session-> {auth };
@@ -115,7 +121,7 @@ sub is_valid_captcha {
115
121
<head>
116
122
<link href="https://fonts.googleapis.com/css?family=Nunito:200,600" rel="stylesheet">
117
123
<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>
119
125
</head>
120
126
<body>
121
127
%= t h1 => 'Login'
@@ -131,13 +137,34 @@ sub is_valid_captcha {
131
137
<br /><br />
132
138
<input type="hidden" id="g-recaptcha-response" name="g-recaptcha-response">
133
139
<input type="hidden" name="action" value="validate_captcha">
134
- %= submit_button 'Log in'
140
+ %= submit_button 'Log in', id => 'submit'
135
141
%= end
136
142
<script>
137
143
function onloadCallback() {
138
144
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) {
140
147
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
+ });
141
168
});
142
169
});
143
170
}
@@ -155,4 +182,3 @@ sub is_valid_captcha {
155
182
@@ denied.html.ep
156
183
%= t h2 => 'Access Denied'
157
184
<a href="<%= url_for('index') %>">Login</a>
158
-
0 commit comments