Skip to content

Commit 1a929a1

Browse files
committed
Added recaptcha v3 example
1 parent d4bb6f0 commit 1a929a1

File tree

9 files changed

+185
-3
lines changed

9 files changed

+185
-3
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,3 +138,4 @@ Hopefully will work on older version too (as old as 5.10) and across diferent OS
138138
| Currency Converter <ul><li>LWP::UserAgent</li></ul><ul><li>Mojo::UserAgent</li></ul> | Completed |
139139
| Weather <ul><li>LWP::UserAgent</li></ul><ul><li>Mojo::UserAgent</li></ul> | Completed |
140140
| reCAPTCHA v2 | Completed |
141+
| reCAPTCHA v3 | Completed |
Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,32 @@
11
# reCAPTCHA verification using Perl
22

3+
34
### v2 verification in login page created using Mojolicious
45

56
To run the script just update it with your 'Site Key' and 'Secret Key' and run -
7+
68
morbo recaptcha_v2_verification.pl
79

8-
![alt text](login_page.PNG?raw=true)
9-
![alt text](recaptcha_v2_verification.PNG?raw=true)
10+
Browse to http://localhost:3000 for the output
11+
12+
![alt text](screenshots/login_page_v2.PNG?raw=true)
13+
![alt text](screenshots/recaptcha_v2_verification.PNG?raw=true)\
14+
15+
16+
### v3 verification in login page created using Mojolicious
17+
18+
To run the script just update it with your 'Site Key' and 'Secret Key' and run -
19+
20+
morbo recaptcha_v3_verification.pl
21+
22+
Browse to http://localhost:3000 for the output -
23+
24+
![alt text](screenshots/login_page_v3.PNG?raw=true)
25+
26+
In case of success user will be able to login -
27+
28+
![alt text](screenshots/login_success.PNG?raw=true)
29+
30+
In case of bot, it will theough error -
31+
32+
![alt text](screenshots/error_for_bot.PNG?raw=true)

web_programming/recaptcha_verification/recaptcha_v2_verification.pl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
# https://metacpan.org/pod/Mojolicious
1010
# https://docs.mojolicious.org/Mojolicious/Lite
11+
# https://developers.google.com/recaptcha/docs/display
1112

1213
# This is a simple Login page. We will be authenticating user.
1314
# After success they will get a home page where we will be welcoming them and they can logout from there.
@@ -24,7 +25,6 @@
2425
sub is_valid_captcha {
2526
my ($c) = @_;
2627
my $ua = Mojo::UserAgent->new;
27-
$ua->insecure(1);
2828
my $param = $c->param('g-recaptcha-response');
2929

3030
my $captcha_url = 'https://www.google.com/recaptcha/api/siteverify';
Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
#!/usr/bin/env perl
2+
3+
# reCAPTCHA is a CAPTCHA system, that is a system that allows web hosts to distinguish between human
4+
# and automated access to websites. More info - https://www.google.com/recaptcha/about/
5+
# You can register your site in google reCAPTCHA at https://www.google.com/recaptcha/admin/create
6+
# You will get 'Site Key' and 'Secret Key'.
7+
# 'Site Key' will be put on front-end side while 'Secret key' will be on server side in environemnt variable.
8+
9+
# https://metacpan.org/pod/Mojolicious
10+
# https://docs.mojolicious.org/Mojolicious/Lite
11+
# https://developers.google.com/recaptcha/docs/v3
12+
13+
# This is a simple Login page. We will be authenticating user.
14+
# After success they will get a home page where we will be welcoming them and they can logout from there.
15+
# In case of authentication failure error will be thrown.
16+
17+
use strict;
18+
use warnings;
19+
use Mojolicious::Lite;
20+
use Mojo::UserAgent;
21+
22+
# Add your 'Secret Key' here
23+
$ENV{'CAPTCHA_V3_SECRET_KEY'} = "";
24+
25+
sub is_valid_captcha {
26+
my ($c) = @_;
27+
my $ua = Mojo::UserAgent->new;
28+
my $param = $c->param('g-recaptcha-response');
29+
my $captcha_url = 'https://www.google.com/recaptcha/api/siteverify';
30+
my $response
31+
= $ua->post(
32+
$captcha_url => form => {response => $param, secret => $ENV{'CAPTCHA_V3_SECRET_KEY'}})
33+
->result;
34+
if ($response->is_success()) {
35+
my $out = $response->json;
36+
# reCAPTCHA v3 returns a score -> 1.0 is very likely a good interaction, 0.0 is very likely a bot
37+
if ($out->{success} && $out->{score} > 0.5) {
38+
return 1;
39+
}
40+
else {
41+
# Its a bot
42+
return 0;
43+
}
44+
}
45+
46+
# Connection to reCAPTCHA failed
47+
return 0;
48+
}
49+
50+
# https://docs.mojolicious.org/Mojolicious/Lite#Helpers
51+
# Check for authentication
52+
helper auth => sub {
53+
my $c = shift;
54+
55+
if (($c->param('username') eq 'admin') && ($c->param('password') eq 'admin')) {
56+
return 1;
57+
}
58+
return 0;
59+
};
60+
61+
helper verify_captcha => sub {
62+
my $c = shift;
63+
if (is_valid_captcha($c)) {
64+
return 1;
65+
}
66+
return 0;
67+
};
68+
69+
# Different Routes
70+
get '/' => sub { shift->render } => 'index';
71+
72+
post '/login' => sub {
73+
my $c = shift;
74+
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+
}
84+
}
85+
$c->flash('error' => 'Wrong login/password');
86+
$c->redirect_to('index');
87+
} => 'login';
88+
89+
get '/logout' => sub {
90+
my $c = shift;
91+
delete $c->session->{auth};
92+
$c->redirect_to('index');
93+
} => 'logout';
94+
95+
# https://docs.mojolicious.org/Mojolicious/Lite#Under
96+
under sub {
97+
my $c = shift;
98+
return 1 if ($c->session('auth') // '') eq '1';
99+
100+
$c->render('denied');
101+
};
102+
103+
get '/home' => sub {
104+
my $c = shift;
105+
$c->render();
106+
} => 'home';
107+
108+
app->start;
109+
110+
__DATA__
111+
112+
113+
@@ index.html.ep
114+
<html>
115+
<head>
116+
<link href="https://fonts.googleapis.com/css?family=Nunito:200,600" rel="stylesheet">
117+
<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>
119+
</head>
120+
<body>
121+
%= t h1 => 'Login'
122+
123+
% if (flash('error')) {
124+
<h2 style="color:red"><%= flash('error') %></h2>
125+
% }
126+
127+
%= form_for login => (method => 'post') => begin
128+
<label>username:</label> <%= text_field 'username' %>
129+
<br /><br />
130+
<label>password:</label> <%= password_field 'password' %>
131+
<br /><br />
132+
<input type="hidden" id="g-recaptcha-response" name="g-recaptcha-response">
133+
<input type="hidden" name="action" value="validate_captcha">
134+
%= submit_button 'Log in'
135+
%= end
136+
<script>
137+
function onloadCallback() {
138+
grecaptcha.ready(function() {
139+
grecaptcha.execute('Your Site Key', {action:'validate_captcha'}).then(function(token) {
140+
document.getElementById('g-recaptcha-response').value = token;
141+
});
142+
});
143+
}
144+
</script>
145+
</body>
146+
</html>
147+
148+
149+
@@ home.html.ep
150+
%= t h1 => 'Home Page'
151+
<h2 style="color:green">Hello <%= flash('username') %></h2>
152+
<a href="<%= url_for('logout') %>">Logout</a>
153+
154+
155+
@@ denied.html.ep
156+
%= t h2 => 'Access Denied'
157+
<a href="<%= url_for('index') %>">Login</a>
158+
16.4 KB
Loading
12.3 KB
Loading
7.61 KB
Loading

0 commit comments

Comments
 (0)