2017-08-08 117 views
-1

我發現了一個如何做一個oauth簽名但是有多維哈希問題的例子。我的哈希看起來像這樣使用數據::自卸車,以顯示我的哈希名爲%的要求:Perl哈希到oauth簽名

$VAR1 = { 'Invoice' => { 'Line' => [ { 'Id' => '1', 'SalesItemLineDetail' => { 'ItemRef' => { 'value' => 'SKM2267' }, 'UnitPrice' => '10.00' }, 'DetailType' => 'SalesItemLineDetail', 'LineNum' => 1 }, { 'Id' => '2', 'SalesItemLineDetail' => { 'ItemRef' => { 'value' => 'SKM2292' }, 'UnitPrice' => '20.00' }, 'DetailType' => 'SalesItemLineDetail', 'LineNum' => 2 }, { 'Id' => '3', 'SalesItemLineDetail' => { 'ItemRef' => { 'value' => 'SKM2285' }, 'UnitPrice' => '30.00' }, 'DetailType' => 'SalesItemLineDetail', 'LineNum' => 3 } ], 'DocNumber' => '90210', 'CustomerRef' => \{ 'name' => 'Amazon.com', 'value' => 1 } } }; 

,使簽名的例子包括加盟%請求哈希入一個字符串:

my $string = join('&',map {$_ . '=' . uri_escape($request{$_})} sort keys %request); 

但這樣就產生了不一致以下用作簽名:

Invoice=HASH%280x7f254c17b540%29 

我該如何處理這個哈希創建我需要傳遞到我的OAuth簽名字符串的字符串?

示例腳本,它做工精細,使用以下構建OAuth的簽名:

my $hmac = Digest::HMAC_SHA1->new($e->{params}{qbo_consumer_secret} . '&' . $e->{params}{qbo_access_token_secret}); 
$hmac->add('GET&' . uri_escape('https://sandbox-quickbooks.api.intuit.com/v3/company/' . $company_id . '/query') . '&' . uri_escape('oauth_consumer_key=' . $consumer_key . '&oauth_nonce=' . $nonce . '&oauth_signature_method=HMAC-SHA1&oauth_timestamp=' . $time . '&oauth_token=' . $access_token . '&oauth_version=1.0' . '&' . join('&',map {$_ . '=' . uri_escape($params{$_})} sort keys %params))); 

相比於我想要什麼:

my $hmac = Digest::HMAC_SHA1->new($e->{params}{qbo_consumer_secret} . '&' . $e->{params}{qbo_access_token_secret}); 
$hmac->add('POST&' . uri_escape($server) . '&' . uri_escape('oauth_consumer_key=' . $e->{params}{qbo_consumer_key}) . '&oauth_nonce=' . $nonce . '&oauth_signature_method=HMAC-SHA1&oauth_timestamp=' . $time . '&oauth_token=' . $e->{params}{qbo_access_token} . '&oauth_version=1.0' . '&' . join('&',map {$_ . '=' . uri_escape($request{$_})} sort keys %request)); 

然後請求包括此授權頭:

my $req = HTTP::Request->new(POST => $server); 
$req->header(Authorization => 
    'OAuth oauth_consumer_key="' . $e->{qbo_consumer_key} 
    . '",oauth_nonce="' . $nonce 
    . '",oauth_signature="' . encode_base64($hmac->digest) 
    . '",oauth_signature_method="HMAC-SHA1' 
    . '",oauth_timestamp="' . time(); 
    . '",oauth_token="' . $e->{qbo_access_token} 
    . '",oauth_version="1.0' 
    . '"'); 
$req->content(\%request); 

另外,試圖將散列轉換爲json結果'can not e ncode引用標量'。我試試這個簡單的測試腳本:

#!/usr/bin/perl 

use strict; 
use warnings; 
use JSON; 

my %hash = { 'Invoice' => { 'Line' => [ { 'Id' => '1', 'SalesItemLineDetail' => { 'ItemRef' => { 'value' => 'SKM2267' }, 'UnitPrice' => '10.00' }, 'DetailType' => 'SalesItemLineDetail', 'LineNum' => 1 }, { 'Id' => '2', 'SalesItemLineDetail' => { 'ItemRef' => { 'value' => 'SKM2292' }, 'UnitPrice' => '20.00' }, 'DetailType' => 'SalesItemLineDetail', 'LineNum' => 2 }, { 'Id' => '3', 'SalesItemLineDetail' => { 'ItemRef' => { 'value' => 'SKM2285' }, 'UnitPrice' => '30.00' }, 'DetailType' => 'SalesItemLineDetail', 'LineNum' => 3 } ], 'DocNumber' => '90210', 'CustomerRef' => \{ 'name' => 'Amazon.com', 'value' => 1 } } }; 

my $js = encode_json \%hash; 
print "$js\n"; 

在下面產生這個錯誤,我的散列有什麼問題嗎?

Reference found where even-sized list expected at testjson.pl line 8. 
{"HASH(0x8db5f3c)":null} 
+0

你究竟想要'uri_escape'? '$ request {$ _}'是一個散列引用,通常不是你想要串聯的東西。 – tjd

+0

是的,我猜測我不需要uri_escape,我使用HMAC包添加函數來構建GET請求的簽名,但我使用POST進行特定的Quickbooks API調用。如何產生一個字符串也會讓我感到困惑,但根據我的理解,這個請求必須是oauth簽名的一部分。我將添加與我正在嘗試執行的操作相比較的示例。 – rwfitzy

+0

在工作示例中,簽名是根據構成HTTP請求的元素(方法,主機和查詢字符串)構造的。你如何使用'%request'來構建'$ req'? –

回答

0

所以,首先,如果你讀了JSON模塊文檔,它非常清楚地指出,encode方法只需要一個標量,從而傳遞一個哈希將無法正常工作。當你將這樣的散列傳遞給一個函數時,它會將每個鍵和值分別傳遞給它們。

my %hash=("a" => 1,"b" => 2); 
my_func(%hash); 
# The above function call is the same as the one below 
my_func("b",2,"a",1); 

它傳遞的順序每個鍵/值的配對都是隨機的,就像你通常用散列找到的那樣。它甚至應該拋出一個錯誤,告訴你如何使用它,或者至少是我已經安裝的版本,當我嘗試測試你的代碼時。

相反,你真正想要做的是通過在hashref這樣

$json->encode(\%request); 

,返回的是你需要傳遞給$req->content()和簽名用的什麼價值。我不知道Quickbooks API的任何內容,無論您是按照原樣傳遞JSON數據,還是將它用作CGI參數的值。它應該是它在他們的文檔中告訴你的東西,我希望。

+0

其實我試過我的$ js = $ json-> encode(\%request);並得到這個錯誤:不能編碼對標量的引用。我會在上面添加更多。 – rwfitzy

+0

@rwfitzy你正在創建你的哈希不正確 - 最外面的哈希創建括號不花括號。查看我的答案,瞭解如何創建散列的示例。內在的是用大括號來完成的 –