Alister West

home is where your code is ...

Perl OAuth - GET json from resource with OAuth headers

I needed to wrap a json oauth request with oauth headers. Net::OAuth::Simple puts them in the query-string by default. After a bunch of digging around available modules I found "WWW::TypePad":http://search.cpan.org/search?query=WWW%2FTypePad.pm did pretty much what I wanted. This seems pretty long winded - when I have tuits I'll have a go at cleaning this up.

package main;
use feature qw/say/;
my $tokens = { consumer_key=>'', consumer_secret=>'',
               access_token=>'', access_token_secret=>'' };
my $urls = {authorization_url=>'',request_token_url=>'',access_token_url=>''};
my $uri = 'http://example.com/something';

my %extra = ( ContentBody => '{ Foo : 1 }', ContentType => 'application/json' );
my $oauth = Net::OAuth::Simple::AuthHeader->new($tokens, $urls);
my $response = $oauth->make_restricted_request( $uri, $method, %extra );

if ( $response->is_redirect ) {
    $response = $oauth->make_restricted_request(
        $response->header( 'Location' ), $method, %extra
    );
}
say $response->content;
exit;

package Local::Net::OAuth::Simple::UA;
# -----------------------------
use base 'LWP::UserAgent';
sub request {
    my ($self, $req, @args) = @_;
    $self->{max_redirect} = 0;
    my $response = $self->SUPER::request($req, @args);
    # Debugging - Show raw HTTP
    say $req->as_string;
    say "Response: ". $response->content . "\n";
    return $response;
}

package Net::OAuth::Simple::AuthHeader;
# -------------------------------------
# From WWW::TypePad
# we need Net::OAuth::Simple to make requests with the OAuth credentials
# in the Authorization header (rather than the query string).
use base qw( Net::OAuth::Simple );

sub new {
    my ($class, $tokens, $urls) = @_;
    return $class->SUPER::new(
        browser => Local::Net::OAuth::Simple::UA->new(),
        protocol_version => '1.0a',
        tokens => $tokens,
        urls   => $urls,   # authorization_url, request_token_url, access_token_url
    );
}

sub make_restricted_request {
    my $self = shift;
    croak $Net::OAuth::Simple::UNAUTHORIZED unless $self->authorized;

    my( $url, $method, %extras ) = @_;

    my $uri = URI->new( $url );
    my %query = $uri->query_form;
    $uri->query_form( {} );

    $method = lc $method;

    my $content_body = delete $extras{ContentBody};
    my $content_type = delete $extras{ContentType};

    my $request = Net::OAuth::ProtectedResourceRequest->new(
        consumer_key     => $self->consumer_key,
        consumer_secret  => $self->consumer_secret,
        request_url      => $uri,
        request_method   => uc( $method ),
        signature_method => $self->signature_method,
        protocol_version => $self->oauth_1_0a ?
            Net::OAuth::PROTOCOL_VERSION_1_0A :
            Net::OAuth::PROTOCOL_VERSION_1_0,
        timestamp        => time,
        nonce            => $self->_nonce,
        token            => $self->access_token,
        token_secret     => $self->access_token_secret,
        extra_params     => { %query, %extras },
    );
    $request->sign;
    die "COULDN'T VERIFY! Check OAuth parameters.\n"
        unless $request->verify;

    my $request_url = URI->new( $url );

    my $req = HTTP::Request->new(uc($method) => $request_url);
    $req->header('Authorization' => $request->to_authorization_header);
    if ($content_body) {
        $req->content_type($content_type);
        $req->content_length(length $content_body);
        $req->content($content_body);
    }

    my $response = $self->{browser}->request($req);
    return $response;
}
By Alister West