perlquestion
gryphon
<p>Greetings great monks,<p>
<p>I wonder if you might be able to help answer a quick question for me with regard to Net::OAuth and POST data. I've been trying to integrate with the TradeKing API, which uses OAuth 1.0a, but I'm running into a problem I can't seem to figure out with regard to POST data. From what I understand, Net::OAuth assumes that all data will be in the form of key/value pairs that are provided to "extra_params", but I can't seem to find a way to provide a single block of POST data so that it can be included in the signing process.</p>
<p>Is there a way using Net::OAuth to include POST data/content so that it will be picked up by the signing process?</p>
<p>More specifically, here are the documentation references I'm using and sample code:</p>
<p><a href="https://developers.tradeking.com/documentation/watchlists-post">https://developers.tradeking.com/documentation/watchlists-post</a><br />
Using POST method to deliver key/value pairs, which I've been able to get working.</p>
<code>#!/usr/bin/env perl
use Modern::Perl '2015';
use Math::Random::MT 'rand';
use Net::OAuth;
use URL::Encode 'url_encode';
use HTTP::Request;
use LWP::UserAgent;
use JSON::XS;
use Data::Dumper 'Dumper';
my %params = (
id => 'watchlist-' . time,
symbols => 'AAPL,MSFT',
);
my $content = join( '&',
map {
url_encode($_) . '=' . url_encode( $params{$_} )
} keys %params
);
my $oauth = Net::OAuth->request('protected resource')->new(
consumer_key => '...',
consumer_secret => '...',
token => '...',
token_secret => '...',
protocol_version => Net::OAuth::PROTOCOL_VERSION_1_0A,
signature_method => 'HMAC-SHA1',
timestamp => time,
nonce => int( rand( 2**32 ) ),
request_url => 'https://api.tradeking.com/v1/watchlists.json',
request_method => 'POST',
extra_params => \%params,
);
$oauth->sign;
my $request = HTTP::Request->new(
$oauth->request_method,
$oauth->request_url,
[
'Authorization' => $oauth->to_authorization_header,
'Content-Type' => 'application/x-www-form-urlencoded',
],
$content,
);
say $request->as_string;
my $response = LWP::UserAgent->new->request($request);
if ( not $response->is_success ) {
say $response->message;
say $response->content;
}
else {
say Dumper( JSON::XS->new->decode( $response->content ) );
}
</code>
<p><a href="https://developers.tradeking.com/documentation/accounts-id-orders-post">https://developers.tradeking.com/documentation/accounts-id-orders-post</a><br />
Using POST data (a single block of content), which I've been unable to get working.</p>
<code>#!/usr/bin/env perl
use Modern::Perl '2015';
use Math::Random::MT 'rand';
use Net::OAuth;
use URL::Encode 'url_encode';
use HTTP::Request;
use LWP::UserAgent;
use JSON::XS;
use Data::Dumper 'Dumper';
my $content = '<?xml version="1.0" encoding="UTF-8"?>
<FIXML xmlns="http://www.fixprotocol.org/FIXML-5-0-SP2">
<Order TmInForce="0" Typ="2" Side="1" Px="13" Acct="38619105">
<Instrmt SecTyp="CS" Sym="AAPL"/>
<OrdQty Qty="1"/> </Order>
</FIXML>';
my $oauth = Net::OAuth->request('protected resource')->new(
consumer_key => '...',
consumer_secret => '...',
token => '...',
token_secret => '...',
protocol_version => Net::OAuth::PROTOCOL_VERSION_1_0A,
signature_method => 'HMAC-SHA1',
timestamp => time,
nonce => int( rand( 2**32 ) ),
request_url => 'https://api.tradeking.com/v1/accounts/38619105/orders.json',
request_method => 'POST',
extra_params => { POSTDATA => $content },
);
$oauth->signature_elements( [ @{ $oauth->signature_elements }, $content ] );
my $request = HTTP::Request->new(
$oauth->request_method,
$oauth->request_url,
[
'Authorization' => $oauth->to_authorization_header,
'Content-Type' => 'application/x-www-form-urlencoded',
'TKI_TRADEPASS' => 'myPass',
'TKI_OVERRIDE' => 'true',
],
$content,
);
say $request->as_string;
my $response = LWP::UserAgent->new->request($request);
if ( not $response->is_success ) {
say $response->message;
say $response->content;
}
else {
say Dumper( JSON::XS->new->decode( $response->content ) );
}
</code>
<p>What's going on in the second code sample here is that I'm trying to get Net::OAuth to "see" the POST data and include it in the creation of the signature. So far, that hasn't happened, so the response I get back from the API is an authentication failure.</p>
<p>Any suggestions would be most appreciated. Thanks very much.</p>
<div class="pmsig"><div class="pmsig-25626">
<p>[gryphon]</p>
</div></div>