OAuth::Lite::Util - utility for OAuth


OAuth-Lite documentation Contained in the OAuth-Lite distribution.

Index


Code Index:

NAME

Top

OAuth::Lite::Util - utility for OAuth

SYNPSIS

Top

    use OAuth::Lite::Util qw(
        gen_random_key
        encode_param
        decode_param
        create_signature_base_string
        parse_auth_header
    );

    my $random = gen_random_key(8);
    my $enocded = encode_param($param);
    my $deocded = decode_param($encoded);

    my $base_string = create_signature_base_string('GET',
        'http://example.com/path?query', $params);

    my $header = q{OAuth realm="http://example.com/api/resource", oauth_consumer_key="hogehoge", ... };
    my ($realm, $oauth_params) = parse_auth_header($header);
    say $realm;
    say $oauth_params->{oauth_consumer_key};
    say $oauth_params->{oauth_version};
    ...

DESCRIPTION

Top

Utilty functions for OAuth are implemented here.

METHODS

Top

gen_random_key($length)

Generate random octet string. You can indicate the byte-length of generated string. (10 is set by default) If 10 is passed, returns 20-length octet string.

    use OAuth::Lite::Util qw(gen_random_key);
    my $key1 = gen_random_key();
    my $key2 = gen_random_key();

encode_param($param)

Encode parameter according to the way defined in OAuth Core spec.

decode_param($encoded_param)

Decode the encoded parameter.

create_signature_base_string($http_method, $request_uri, $params);

    my $method = "GET";
    my $uri = "http://example.com/api/for/some-resource";
    my $parmas = {
        oauth_consumer_key     => 'foo-bar',
        oauth_signature_method => 'HMAC-SHA1',
        oauth_version => '1.0',
        ...
    };
    my $base_string = create_signature_base_string($method, $uri, $params);

normalize_request_url($url);

Normalize url according to the way the OAuth Core spec defines.

    my $string = normalize_request_url('http://Example.com:80/path?query');
    # http://example.com/path
    my $string = normalize_request_url('https://Example.com:443/path?query');
    # https://example.com/path
    my $string = normalize_request_url('http://Example.com:8080/path?query');
    # http://example.com:8080/path

normalize_params($params);

Sort and encode params and concatenates them according to the way OAuth Core spec defines.

    my $string = normalize_params({
        a => 1, c => 'hi%20there', f => [25, 50, 'a'], z => [ 'p', 't' ]
    });

parse_auth_header($header)

Parse authorization/www-authentication header for OAuth. And return the realm and other params.

    # service provider side
    my $header = $r->headers_in->{Authorization};
    my ($realm, $params) = parse_auth_header($header);
    say $params->{oauth_token};
    say $params->{oauth_consumer_key};
    say $params->{oauth_signature_method};
    ...

    # consumer side
    my $header = $res->header('WWW-Authenticate');
    my ($realm) = parse_auth_header($header);

build_auth_header(%params)

    my $header = build_auth_header($realm, {
        oauth_consumer_key     => '...', 
        oauth_signature_method => '...',
        ... and other oauth params
    });

AUTHOR

Top

Lyo Kato, lyo.kato _at_ gmail.com

COPYRIGHT AND LICENSE

Top


OAuth-Lite documentation Contained in the OAuth-Lite distribution.
package OAuth::Lite::Util;

use strict;
use warnings;

use URI;
use URI::Escape;
use Crypt::OpenSSL::Random;
use Carp ();

use base 'Exporter';

our %EXPORT_TAGS = ( all => [qw/
    gen_random_key
    encode_param
    decode_param
    create_signature_base_string
    parse_auth_header
    build_auth_header
    normalize_params
/]);

our @EXPORT_OK = map { @$_ } values %EXPORT_TAGS;

sub gen_random_key {
    my $length = shift || 10;
    return unpack("H*", Crypt::OpenSSL::Random::random_bytes($length));
}

sub encode_param {
    my $param = shift;
    URI::Escape::uri_escape($param, '^\w.~-');
}

sub decode_param {
    my $param = shift;
    URI::Escape::uri_unescape($param);
}

sub create_signature_base_string {
    my ($method, $url, $params) = @_;
    $method = uc $method;
    $params = {%$params};
    delete $params->{oauth_signature};
    delete $params->{realm};
    my $normalized_request_url = normalize_request_url($url);
    my $normalized_params = normalize_params($params);
    my $signature_base_string = join('&', map(encode_param($_),
        $method, $normalized_request_url, $normalized_params));
    $signature_base_string;
}

sub normalize_request_url {
    my $uri = shift;
    $uri = URI->new($uri) unless (ref $uri && ref $uri eq 'URI');
    unless (lc $uri->scheme eq 'http' || lc $uri->scheme eq 'https') {
        Carp::croak qq/Invalid request url, "$uri"/;
    }
    my $port = $uri->port;
    my $request_url = ($port && ($port == 80 || $port == 443))
        ? sprintf(q{%s://%s%s}, lc($uri->scheme), lc($uri->host), $uri->path)
        : sprintf(q{%s://%s:%d%s}, lc($uri->scheme), lc($uri->host), $port, $uri->path);
    $request_url;
}

sub normalize_params {
    my $params = shift;
    my @pairs = ();
    for my $k (sort keys %$params) {
        if (!ref $params->{$k}) {
            push @pairs, 
                sprintf(q{%s=%s}, encode_param($k), encode_param($params->{$k}));
        }
        elsif (ref $params->{$k} eq 'ARRAY') {
            for my $v (sort @{ $params->{$k} }) {
                push @pairs, 
                    sprintf(q{%s=%s}, encode_param($k), encode_param($v));
            }
        }
    }
    return join('&', @pairs);
}

sub parse_auth_header {
    my $header = shift;
    $header =~ s/^\s*OAuth\s*//;
    my $params = {};
    for my $attr (split /,\s*/, $header) {
        my ($key, $val) = split /=/, $attr, 2;
        $val =~ s/^"//;
        $val =~ s/"$//;
        $params->{$key} = decode_param($val);
    }
    my $realm = delete $params->{realm};
    return wantarray ? ($realm, $params) : $realm;
}

sub build_auth_header {
    my ($realm, $params) = @_;
    my $head = sprintf q{OAuth realm="%s"}, $realm || '';
    my $authorization_header = join(', ', $head,
        sort { $a cmp $b } map(sprintf(q{%s="%s"}, encode_param($_), encode_param($params->{$_})),
            grep { /^x?oauth_/ } keys %$params));
    $authorization_header;
}

1;