Captcha-reCAPTCHA-V2/lib/Captcha/reCAPTCHA/V2.pm
package Captcha::reCAPTCHA::V2;
use strict;
use warnings;
use Carp;
use HTTP::Tiny;
use JSON;
# ABSTRACT: A Perl implementation of reCAPTCHA API version 2
our $VERSION = '0.3'; # VERSION
sub new {
my $class = shift;
my $self = bless {}, $class;
# Initialize the user agent object
$self->{ua} = HTTP::Tiny->new(
agent => 'Captcha::reCAPTCHA::V2/'.
($Captcha::reCAPTCHA::V2::VERSION || 0) . ' (Perl)'
);
$self->{widget_api} = 'https://www.google.com/recaptcha/api.js?'.
'onload=onloadCallback&render=explicit';
$self->{verify_api} = 'https://www.google.com/recaptcha/api/siteverify';
return $self;
}
sub _element_id {
my ($key) = @_;
return 'recaptcha_' . substr($key, 0, 10);
}
sub _recaptcha_script {
my ($self, $sitekey, $options) = @_;
my $json_options = to_json({ sitekey => $sitekey, %$options }, $self->{json_options} || {});
return '<script type="text/javascript">var onloadCallback = function(){grecaptcha.render(\''
. _element_id($sitekey) . '\',' . $json_options . ');};</script>';
}
sub html {
my ($self, $sitekey, $options) = @_;
$options ||= {};
if (!defined $sitekey) {
croak 'Site key is required to use reCAPTCHA';
}
unless (ref $options eq "HASH") {
croak 'Options must be a reference to hash';
}
my $script = $self->_recaptcha_script($sitekey, $options);
return join(
'',
$script,
'<script src="' . $self->{widget_api} . '" type="text/javascript"></script>',
'<div id="'. _element_id($sitekey) . '"></div>',
);
}
sub verify {
my ($self, $secret, $response, $remoteip) = @_;
if (!defined $secret) {
croak 'Secret key is required to verify reCAPTCHA';
}
if (!defined $response) {
croak 'Response from user is required to verify reCAPTCHA';
}
my $params = {
secret => $secret,
response => $response,
};
$params->{remoteip} = $remoteip if defined $remoteip;
my $res = $self->{ua}->post_form(
$self->{verify_api},
$params
);
if ($res->{success}) {
my $content = decode_json $res->{content};
if ($content->{success}){
return { success => 1 };
} else {
return { success => 0, error_codes => $content->{'error-codes'} };
}
}
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Captcha::reCAPTCHA::V2 - A Perl implementation of reCAPTCHA API version 2
=head1 VERSION
version 0.3
=head1 SYNOPSIS
Captcha::reCAPTCHA::V2 enables you to integrate reCAPTCHA version 2 into your
web application.
use Captcha::reCAPTCHA::V2;
# Create a new instance of Captcha::reCAPTCHA::V2
my $rc = Captcha::reCAPTCHA::V2->new;
# Get HTML code to display the reCAPTCHA
my $rc_html = $rc->html('site key');
# Verify user's response
my $result = $rc->verify('secret', $response);
if ($result->{success}){
# Good
} else {
# Bad -- get first error that was returned
$error = $result->{error_codes}->[0];
}
=head1 METHODS
=head2 new
Creates a new instance of Captcha::reCAPTCHA::V2.
my $rc = Captcha::reCAPTCHA::V2->new;
=head2 html
Returns the HTML code for rendering the reCAPTCHA widget.
my $html = $rc->html('site key', { theme => 'dark' });
Parameters:
=over 4
=item * C<$sitekey>
B<(Required)> The site's public key provided by API
=item * C<$options>
A reference to a hash of options that affect the appearance and behavior of the
reCAPTCHA widget. Available options:
=over
=item * C<theme>
The color theme of the widget. Possible values are C<'dark'> and C<'light'>.
=item * C<type>
The type of the captcha to serve. Possible values are C<'audio'> and
C<'image'>.
=item * C<size>
The size of the widget. Possible values are C<'compact'> and C<'normal'>.
=back
=back
See also: L<grecaptcha.render parameters|https://developers.google.com/recaptcha/docs/display#render_param>.
=head2 verify
Verifies the user's response.
my $result = $rc->verify('secret', $response);
if ($result->{success}) {
# ...
}
Parameters:
=over 4
=item * C<$secret>
B<(Required)> The site's secret key provided by API
=item * C<$response>
B<(Required)> Response string retrieved from the submitted form field
C<g-recaptcha-response>.
=item * C<$remoteip>
IP address of the user.
=back
Returns a reference to a hash containing two fields: C<success> and C<error_codes>.
=head1 SEE ALSO
=over 4
=back
* L<Captcha::reCAPTCHA>
* L<Google reCAPTCHA API Reference|https://www.google.com/recaptcha/intro/index.html/>
=head1 ACKNOWLEDGEMENTS
Based on Andy Armstrong's a perl implementation of the reCAPTCHA API version 1
(Captcha::reCAPTCHA).
=for :stopwords cpan testmatrix url annocpan anno bugtracker rt cpants kwalitee diff irc mailto metadata placeholders metacpan
=head1 SUPPORT
=head2 Bugs / Feature Requests
Please report any bugs or feature requests through the issue tracker
at L<https://github.com/Sidnet/p5-Captcha-reCAPTCHA-V2/issues>.
You will be notified automatically of any progress on your issue.
=head2 Source Code
This is open source software. The code repository is available for
public review and contribution under the terms of the license.
L<https://github.com/Sidnet/p5-Captcha-reCAPTCHA-V2>
git clone https://github.com/Sidnet/p5-Captcha-reCAPTCHA-V2.git
=head1 AUTHOR
Pattawan Kaewduangdee <pattawan@cpan.org>
=head1 CONTRIBUTOR
=for stopwords Michal Wojciechowski
Michal Wojciechowski <odyniec@cpan.org>
=head1 COPYRIGHT AND LICENSE
This software is copyright (c) 2015 by Pattawan Kaewduangdee.
This is free software; you can redistribute it and/or modify it under
the same terms as the Perl 5 programming language system itself.
=cut