NAME

OAuth::Lite::Consumer - consumer agent

SYNOPSIS

my $consumer = OAuth::Lite::Consumer->new(
    consumer_key       => $consumer_key,
    consumer_secret    => $consumer_secret,
    site               => q{http://api.example.org},
    request_token_path => q{/request_token},
    access_token_path  => q{/access_token},
    authorize_path     => q{http://example.org/authorize},
);

# At first you have to publish request-token, and
# with it, redirect end-user to authorization-url that Service Provider tell you beforehand.

my $request_token = $consumer->get_request_token(
    callback_url => q{http://yourservice/callback},
);

$your_app->session->set( request_token => $request_token );

$your_app->redirect( $consumer->url_to_authorize(
    token        => $request_token,
) );

# After user authorize the request on a Service Provider side web application.

my $verifier = $your_app->request->param('oauth_verifier');
my $request_token = $your_app->session->get('request_token');

my $access_token = $consumer->get_access_token(
    token    => $request_token,
    verifier => $verifier,
);

$your_app->session->set( access_token => $access_token );
$your_app->session->remove('request_token');

# After all, you can request protected-resources with access token

my $access_token = $your_app->session->get('access_token');

my $res = $consumer->request(
    method => 'GET',
    url    => q{http://api.example.org/picture},
    token  => $access_token,
    params => { file => 'mypic.jpg', size => 'small' },
);

unless ($res->is_success) {
    if ($res->status == 400 || $res->status == 401) {
        my $auth_header = $res->header('WWW-Authenticate');
        if ($auth_header && $auth_header =~ /^OAuth/) {
            # access token may be expired,
            # get request-token and authorize again
        } else {
            # another auth error.
        }
    }
    # another error.
}

# OAuth::Lite::Agent automatically adds Accept-Encoding gzip header to
# request, so, when you use default agent, call decoded_content.
my $resource = $res->decoded_content || $res->content;

$your_app->handle_resource($resource);

DESCRIPTION

This module helps you to build OAuth Consumer application.

PAY ATTENTION

If you use OAuth 1.31 or older version, its has invalid way to normalize params. (when there are two or more same key and they contain ASCII and non ASCII value)

But the many services have already supported deprecated version, and the correct way breaks backward compatibility. So, from 1.32, supported both correct and deprecated method.

use $OAuth::Lite::USE_DEPRECATED_NORMALIZER to switch behaviour. Currently 1 is set by default to keep backward compatibility.

use OAuth::Lite::Consumer;
use OAuth::Lite;

$OAuth::Lite::USE_DEPRECATED_NORMALIZER = 0;
...

METHODS

new(%args)

parameters

consumer_key

consumer_key value

consumer_secret

consumer_secret value

signature_method

Signature method you can choose from 'HMAC-SHA1', 'PLAINTEXT', and 'RSA-SHA1' (optional, 'HMAC-SHA1' is set by default)

http_method

HTTP method (GET or POST) when the request is for request token or access token. (optional, 'POST' is set by default)

auth_method

OAuth::Lite::AuthMethod's value you can choose from AUTH_HEADER, POST_BODY and URL_QUERY (optional, AUTH_HEADER is set by default)

realm

The OAuth realm value for a protected-resource you wanto to access to. (optional. empty-string is set by default)

use_request_body_hash

If you use Request Body Hash extension, set 1. See Also http://oauth.googlecode.com/svn/spec/ext/body_hash/1.0/drafts/4/spec.html

site

The base site url of Service Provider

ua

An instance of OAuth::Lite::Agent used to request. (optional)

request_token_path
access_token_path
authorize_path
callback_url

Site and other paths, simple usage.

my $consumer = OAuth::Lite::Consumer->new(
    ...
    site => q{http://example.org},
    request_token_path => q{/request_token},
    access_token_path  => q{/access_token},
    authorize_path     => q{/authorize},
);

say $consumer->request_token_url; # http://example.org/request_token
say $consumer->access_token_url;  # http://example.org/access_token
say $consumer->authorization_url; # http://example.org/authorize

If the authorization_url is run under another domain, for example.

my $consumer = OAuth::Lite::Consumer->new(
    ...
    site => q{http://api.example.org}, 
    request_token_path => q{/request_token},
    access_token_path  => q{/access_token},
    authorize_path     => q{http://www.example.org/authorize},
);
say $consumer->request_token_url; # http://api.example.org/request_token
say $consumer->access_token_url;  # http://api.example.org/access_token
say $consumer->authorization_url; # http://www.example.org/authorize

Like this, if you pass absolute url, consumer uses them as it is.

You can omit site param, if you pass all paths as absolute url.

my $consumer = OAuth::Lite::Consumer->new(
    ...
    request_token_path => q{http://api.example.org/request_token},
    access_token_path  => q{http://api.example.org/access_token},
    authorize_path     => q{http://www.example.org/authorize},
);

And there is a flexible way.

# don't set each paths here.
my $consumer = OAuth::Lite::Consumer->new(
    consumer_key    => $consumer_key,
    consumer_secret => $consumer_secret,
);

# set request token url here directly
my $rtoken = $consumer->get_request_token(
    url          => q{http://api.example.org/request_token},
    callback_url => q{http://www.yourservice/callback},
);

# set authorize path here directly
my $url = $consumer->url_to_authorize(
    token        => $rtoken,
    url          => q{http://www.example.org/authorize},
);

# set access token url here directly
my $atoken = $consumer->get_access_token(
    url      => q{http://api.example.org/access_token},
    verifier => $verfication_code,
);

So does callback_url. You can set it on consutructor or get_request_token method directly.

my $consumer = OAuth::Lite::Consumer->new(
    ...
    callback_url => q{http://www.yourservice/callback},
);
...
my $url = $consumer->get_request_token();

Or

my $consumer = OAuth::Lite::Consumer->new(
    ...
);
...
my $url = $consumer->get_request_token(
    callback_url => q{http://www.yourservice/callback},
);

request_token_url

access_token_url

authorization_url

url_to_authorize(%params)

parameters

url

authorization url, you can omit this if you set authorization_path on constructor.

token

request token value

my $url = $consumer->url_to_authorize(
    url          => q{http://example.org/authorize}, 
    token        => $request_token,
    callback_url => q{http://www.yousrservice/callback},
);

obtain_request_token(%params)

Returns a request token as an OAuth::Lite::Response object. Except for that, this method behaves same as get_request_token.

get_request_token(%params)

Returns a request token as an OAuth::Lite::Token object.

parameters

url

Request token url. You can omit this if you set request_token_path on constructor

realm

Realm for the resource you want to access to. You can omit this if you set realm on constructor.

callback_url

Url which service provider redirect end-user to after authorization. You can omit this if you set callback_url on constructor.

my $token = $consumer->get_request_token(
    url   => q{http://api.example.org/request_token},
    realm => q{http://api.example.org/picture},
) or die $consumer->errstr;

say $token->token;
say $token->secret;

obtain_access_token

my $res = $consumer->obtain_access_token(
    url    => $access_token_url,
    params => {
        x_auth_username => "myname",
        x_auth_password => "mypass",
        x_auth_mode     => "client_auth",
    },
);

my $access_token = $res->token;
say $acces_token->token;
say $acces_token->secret;
my $expires = $res->param('x_auth_expires');

What is the difference between obtain_access_token and get_access_token? get_access_token requires token and verifier. obtain_access_token doesn't. these parameters are optional. You can pass extra parameters like above example.(see x_auth_XXX parameters) And get_access_token returns OAuth::Lite::Token object directly, obtain_access_token returns OAuth::Lite::Response object that includes not only Token object but also other response parameters. the extra parameters are used for some extensions.(Session extension, xAuth, etc.)

Of cource, if you don't need to handle these extensions, You can continue to use get_access_token for backward compatibility.

my $token = $consumer->get_access_token(
    url      => $access_token_url,
    token    => $request_token,
    verifier => $verification_code,
);

# above code's behavior is same as (but response objects are different)

my $res = $consumer->obtain_access_token(
    url => $access_token_url,
    token => $request_token,
    params => {
        oauth_verifier => $verification_code, 
    },
);

get_access_token(%params)

Returns a access token as an OAuth::Lite::Token object.

parameters

url

Request token url. You can omit this if you set request_token_path on constructor

realm

Realm for the resource you want to access to. You can omit this if you set realm on constructor.

token

Request token object.

verifier

Verfication code which provider returns.

my $token = $consumer->get_access_token(
    url      => q{http://api.example.org/request_token},
    realm    => q{http://api.example.org/picture},
    token    => $request_token,
    verifier => $verification_code,
) or die $consumer->errstr;

say $token->token;
say $token->secret;

gen_oauth_request(%args)

Returns HTTP::Request object.

my $req = $consumer->gen_oauth_request(
    method  => 'GET', 
    url     => 'http://example.com/',
    headers => [ Accept => q{...}, 'Content-Type' => q{...}, ... ],
    content => $content,
    realm   => $realm,
    token   => $token,
    params  => { file => 'mypic.jpg', size => 'small' },
);

request(%params)

Returns HTTP::Response object.

parameters

realm

Realm for a resource you want to access

token

Access token OAuth::Lite::Token object

method

HTTP method.

url

Request URL

parmas

Extra params.

content

body data sent when method is POST or PUT.

my $response = $consumer->request(
    method  => 'POST',
    url     => 'http://api.example.com/picture',
    headers => [ Accept => q{...}, 'Content-Type' => q{...}, ... ],
    content => $content,
    realm   => $realm,
    token   => $access_token,
    params  => { file => 'mypic.jpg', size => 'small' },
);

unless ($response->is_success) {
    ...
}

get

There are simple methods to request protected resources. You need to obtain access token and set it to consumer beforehand.

my $access_token = $consumer->get_access_token(
    token    => $request_token,
    verifier => $verifier,
);
# when successfully got an access-token,
# it internally execute saving method like following line.
# $consumer->access_token( $access_token )

or my $access_token = $your_app->pick_up_saved_access_token(); $consumer->access_token($access_token);

Then you can access protected resource in a simple way.

my $res = $consumer->get( 'http://api.example.com/pictures' );
if ($res->is_success) {
    say $res->decoded_content||$res->content;
}

This is same as

my $res = $consumer->request(
    method => q{GET},
    url    => q{http://api.example.com/picture},
);
if ($res->is_success) {
    say $res->decoded_content||$res->content;
}

post

$res = $consumer->post( 'http://api.example.com/pictures', $content );
if ($res->is_success) {
    ...
}

This is same as

$res = $consumer->request(
    method  => q{POST},
    url     => q{http://api.example.com/picture},
    content => $content,
);
if ($res->is_success) {
    ...
}

put

$res = $consumer->put( 'http://api.example.com/pictures', $content );
if ($res->is_success) {
    ...
}

This is same as

my $res = $consumer->request(
    method  => q{PUT},
    url     => q{http://api.example.com/picture},
    content => $content,
);
if ($res->is_success) {
    ...
}

delete

my $res = $consumer->delete('http://api.example.com/delete');
if ($res->is_success) {
    ...
}

This is same as

my $res = $consumer->request(
    method  => q{DELETE},
    url     => q{http://api.example.com/picture},
);
if ($res->is_success) {
    ...
}

find_realm_from_last_response

gen_auth_header($http_method, $request_url, $params);

parameters

realm

realm for a resource you want to access

token

OAuth::Lite::Token object(optional)

my $header = $consumer->gen_auth_header($method, $url, {
    realm => $realm,
    token => $token,
});

gen_auth_query($http_method, $ruqest_url, $token, $extra)

gen_auth_params($http_method, $request_url, [$token])

Generates and returns all oauth params.

my $params = $consumer->gen_auth_params($http_method, $request_url);
say $params->{oauth_consumer_key};
say $params->{oauth_timestamp};
say $params->{oauth_nonce};
say $params->{oauth_signature_method};
say $params->{oauth_signature};
say $params->{oauth_version};

If you pass token as third argument, the result includes oauth_token value.

my $params = $consumer->gen_auth_params($http_method, $request_url, $token);
say $params->{oauth_consumer_key};
say $params->{oauth_timestamp};
say $params->{oauth_nonce};
say $params->{oauth_signature_method};
say $params->{oauth_signature};
say $params->{oauth_token};
say $params->{oauth_version};

oauth_request

oauth_req

Returns last oauth request.

my $req_token = $consumer->get_request_token(...);
say $consumer->oauth_request->uri;

my $req_token = $consumer->get_access_token(...);
say $consumer->oauth_request->uri;

oauth_response

oauth_res

Returns last oauth response.

my $req_token = $consumer->get_request_token(...);
say $consumer->oauth_response->status;

my $req_token = $consumer->get_access_token(...);
say $consumer->oauth_response->status;

oauth_clear

remove last oauth-request and oauth-response.

build_body_hash

Build body hash according to the spec for 'OAuth Request Body Hash extension' http://oauth.googlecode.com/svn/spec/ext/body_hash/1.0/drafts/4/spec.html

my $hash = $self->build_body_hash($content);

AUTHOR

Lyo Kato, lyo.kato _at_ gmail.com

COPYRIGHT AND LICENSE

This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself, either Perl version 5.8.6 or, at your option, any later version of Perl 5 you may have available.