package OAuth::Simple;
use 5.010;
use strict;
use warnings;
use HTTP::Request::Common;
require LWP::UserAgent;
require JSON;
require Carp;
our $VERSION = '1.03';
sub new {
my $class = shift;
my $self = bless {@_}, $class;
Carp::croak("app_id, secret and postback required for this action")
unless ($self->{app_id} && $self->{secret} && $self->{postback});
$self->{ua} ||= LWP::UserAgent->new();
$self->{json} ||= JSON->new;
return $self;
}
sub authorize {
my ($self, $params) = @_;
my %params; %params = %$params if $params && %$params;
my $url = delete $params{url};
Carp::croak("Authorize method URL required for this action") unless ($url);
$url = URI->new($url);
$url->query_form(
client_id => $self->{app_id},
redirect_uri => $self->{postback},
%params,
);
return $url;
}
sub request_access_token {
my ( $self, $params ) = @_;
my %params; %params = %$params if $params && %$params;
my ( $url, $code, $raw, $http_method ) = delete @params{ qw(url code raw http_method) };
Carp::croak("code and url required for this action") unless $code && $url;
my $response = $self->{ua}->request($self->prepare_http_request(
url => $url,
http_method => $http_method,
params => {
client_secret => $self->{secret},
client_id => $self->{app_id},
code => $code,
redirect_uri => $self->{postback},
%params,
},
));
return $response->decoded_content unless $response->is_success;
return $response->content if $raw;
return $self->{json}->decode($response->content);
}
sub request_data {
my ( $self, $params ) = @_;
my %params; %params = %$params if $params && %$params;
my ( $url, $access_token, $raw, $http_method, $token_name ) =
delete @params{ qw(url access_token raw http_method token_name) };
Carp::croak("url required for this action")
unless ($url);
Carp::croak("access_token required for this action")
unless ($access_token || $self->{no_token});
my $response = $self->{ua}->request($self->prepare_http_request(
url => $url,
http_method => $http_method,
params => {
$self->{no_token} ? () : ( ($token_name || 'access_token') => $access_token ),
%params
},
));
return 0 unless $response->is_success;
return $response->content if $raw;
return $self->{json}->decode($response->content);
}
sub prepare_http_request {
my ( $self, %params ) = @_;
$params{http_method} ||= 'GET';
my $req;
if ($params{http_method} eq 'GET') {
my $url = URI->new($params{url});
$url->query_form( %{$params{params}} ) if $params{params};
$req = GET $url;
}
else {
$req = POST $params{url},
$self->{headers} && %{ $self->{headers} } ? %{ $self->{headers} } : (),
Content => $params{params};
}
return $req;
}
1;
__END__
=pod
=head1 NAME
OAuth::Simple - Simple OAuth authorization on your site
=head1 SYNOPSIS
my $oauth = OAuth::Simple->new(
app_id => 'YOUR APP ID',
secret => 'YOUR APP SECRET',
postback => 'POSTBACK URL',
);
my $url = $oauth->authorize( {url => 'https://www.facebook.com/dialog/oauth', scope => 'email', response_type => 'code'} );
# Your web app redirect method.
$self->redirect($url);
# Get access_token.
# Facebook returns data not in JSON. Use the raw mode and parse.
my $access = $oauth->request_access_token( {url => 'https://graph.facebook.com/oauth/access_token', code => $args->{code}, raw => 1} );
# Get user profile data.
my $profile_data = $oauth->request_data( {url => 'https://graph.facebook.com/me', access_token => $access} );
=head1 DESCRIPTION
Use this module for input VK OAuth authorization on your site
=head1 METHODS
=head2 new
my $oauth = OAuth::Simple->new(
app_id => 'YOUR APP ID',
secret => 'YOUR APP SECRET',
postback => 'POSTBACK URL',
);
The C<new> constructor lets you create a new B<OAuth::Simple> object.
=head2 authorize
my $url = $oauth->authorize( {url => $authorize_server_url, option => 'value'} );
# Your web app redirect method.
$self->redirect($url);
This method returns a URL, for which you want to redirect the user.
=head3 Options
See information about options on your OAuth server.
=head3 Response
Method returns URI object.
=head2 request_access_token
my $access = $oauth->request_access_token( {url => $server_url, code => $args->{code}} );
This method gets access token from OAuth server.
=head3 Options
* code - returned in redirected get request from authorize API method;
* raw - do not decode JSON, return raw data;
* http_method - set http method: GET(default), POST, etc.
=head3 Response
Method returns HASH object.
=head2 request_data
my $profile_data = $oauth->request( {
url => $api_method_url,
access_token => $access_token,
raw => 1,
http_method => 'POST',
token_name => 'ouath_token',
});
This method sends requests to OAuth server.
=head3 Options
* url (required) - api method url;
* params (not required) - other custom params on OAuth server;
* access_token (required) - access token;
* raw - do not decode JSON, return raw data (default 0);
* http_method - set http method: GET(default), POST, etc;
* token_name - access token parameter name (default 'access_token').
=head3 Response
Method returns HASH object with requested data.
=head2 prepare_http_request
Returns HTTP::Request object.
=head1 OBJECT OPTIONS
=head2 no_token
If this parameter is 1, OAuth::Simple will not add access token parameter in request body.
This option can be needed on working with The OAuth 2.0 Authorization Framework: Bearer Token Usage services.
This services accepts access tokens only in special HTTP header.
OAuth::Simple->new(no_token => 1);
=head2 headers
Set HTTP headers, which used in prepare_http_request method.
OAuth::Simple->new( headers => { Content_Type => 'form-data' } );
=head1 SUPPORT
Github: https://github.com/Foxcool/OAuth-Simple
Bugs & Issues: https://github.com/Foxcool/OAuth-Simple/issues
=head1 AUTHOR
Alexander Babenko (foxcool@cpan.org) for Setup.ru (http://setup.ru)
=head1 CONTRIBUTORS
sugar: Anton Ukolov (aukolov@aukolov.ru)
=head1 COPYRIGHT
Copyright (c) 2012 - 2013 Alexander Babenko.
=cut