2014-09-28 92 views
0

我似乎無法在SO甚至Google的任何地方找到這個答案 - 我有一個oauth簽名的Flickr調用上傳API,並遵循the docs我已經按照通常的oauth方式(但沒有photo數據)簽署POST操作。出於測試目的,我只能沿着titlephoto數據傳遞,這意味着我結束了一個包含以下網址張貼到VAR flickrURI:在這個問題當用oauth簽名發佈數據時,Flickr API拋出「無效的API密鑰(密鑰具有無效格式)」

https://api.flickr.com/services/upload/ 
? format=json 
& oauth_consumer_key=... 
& oauth_nonce=2e57b73fec6630a30588e22383cc3b25 
& oauth_signature_method=HMAC-SHA1 
& oauth_timestamp=1411933792346 
& oauth_token=... 
& title=test 
& oauth_signature=O7JPn1m06vl5Rl95Z2in32YWp7Q%3D 

(拆分爲多行是爲了便於閱讀,由於顯而易見的原因,實際的URL在?&周圍沒有空白)。

oauth簽名本身是非常正確的,代碼用於以正確的行爲訪問not-upload-API,所以看起來幾乎不可能得到錯誤的簽名,除了可能簽名「數據不夠」或者可能使用「太多數據」簽名。

中的授權簽名首先形成在auth查詢字符串,在這種情況下:

oauth_consumer_key=... 
&oauth_nonce=60028905f65cf9d7649b3bce98f718f8 
&oauth_signature_method=HMAC-SHA1 
&oauth_timestamp=1411939726691 
&oauth_token=... 
&title=test 

,然後將其用於形成動詞+地址+編碼的基本字符串:

POST&https%3A%2F%2Fapi.flickr.com%2Fservices%2Fupload%2F&oauth_consumer_key%3D...%26oauth_nonce%3D60028905f65cf9d7649b3bce98f718f8%26oauth_signature_method%3DHMAC -SHA1%26oauth_timestamp%3D1411939726691%26oauth_token%3D...%26title%3Dtest

這然後使用Flickr和oauth祕密消化HMAC-SHA1:

function sign = (data, key, secret) { 
    var hmacKey = key + "&" + (secret ? secret : ''), 
     hmac = crypto.createHmac("SHA1", hmacKey); 
    hmac.update(data); 
    var digest = hmac.digest("base64"); 
    return encodeURIComponent(digest); 
} 

並且對於GET請求,這可以很好地工作。 POST請求的事情似乎不同,儘管文檔沒有說明哪個部分是所謂的不同,所以我將嘗試使用的NodeJS request包對在什麼似乎是一個正常的方式POST操作,使用:

uploadOptions = { 
    oauth_consumer_key = auth.api_key, 
    oauth_nonce = auth.oauth_nonce, 
    oauth_timestamp = auth.oauth_timestamp, 
    oauth_token = auth.access_token, 
    oauth_signature_method = "HMAC-SHA1", 
    title: title, 
    photo: <binary data buffer> 
}; 

flickrURL = formSignedURL(auth); 

request.post({ 
    url: flickrURI, 
    headers: { 
    "Authorization": 'oauth_consumer_key="...",oauth_token="...",oauth_signature_method="HMAC-SHA1",oauth_signature="...",oauth_timestamp="...",oauth_nonce="...",oauth_version="1.0"' 
    }, 
    multipart: [{ 
    'content-type': 'application/json', 
    body: JSON.stringify(signOptions) 
    }] 
},function(error, response, body) { 
    console.log("error"); 
    console.log(error); 
    console.log("body"); 
    console.log(body); 
    } 
); 

這將產生一個包含體:

<?xml version="1.0" encoding="utf-8" ?> 
<rsp stat="fail"> 
    <err code="100" msg="Invalid API Key (Key has invalid format)" /> 
</rsp> 

因爲OAuth簽署並沒有真正給我一個選擇,其中API密鑰提供(只有一個),並簽署工作就好了不上傳API,我無法弄清楚這個錯誤消息是想告訴我什麼。關鍵是絕對正確的格式,因爲這是Flickr給你的格式,而且它是正確的值,因爲它在上傳之外工作得很好。我還確保通過「刪除」權限(儘可能廣泛的權限)獲取該密鑰的oauth標記和密鑰,以便包含的訪問標記和訪問標記密鑰應該通過「此標記是否具有寫入權限」測試。

我在這裏錯過了什麼是顯而易見的事情,這阻止了上傳過程?

回答

0

事實證明,將數據添加爲request.post多部分信息不夠好,並且會使Flickr API拋出一個「無效的API密鑰(密鑰無效格式)」錯誤,而不是說出實際錯誤。下面request調用,具有完全相同的數據,工作原理:

var uploadOptions = ... 

var flickrURL = ...; 

var req = request.post(flickrURL, function(error, response, body) { 
    callback(error, body); 
}); 

var form = req.form(); 
uploadOptions.photo = fs.createReadStream(...); 
Object.keys(photoOptions).forEach(function(prop) { 
    form.append(prop, photoOptions[prop]); 
}); 

儘管賺不到那麼多意義上的呼叫明智的(爲什麼會在POST尚未被我們稱之爲form = req.form()的時間做了什麼?)這是一個請求的「正確「的方式通過電線發送POST負載,並使Flickr API處理照片上傳得很好。

0

看起來您正在使用https://up.flickr.com/services/upload/端點,該端點使用舊的身份驗證方案。

對於OAuth,它應該是https://api.flickr.com/services/upload/。確保端點包含在簽名過程中。

我不認爲這是記錄在任何地方,但我記得有相同的問題回來。

+0

當然,至少也會是https?除此之外,更新後的URL仍然會得到無效的API密鑰。我已經更新了這個問題(是的,URl用於簽名,因爲VERB + url + queryarg並置) – 2014-09-29 03:23:05

+0

是的,它應該是https。我剛剛編輯它。 – ikumen 2014-09-29 03:25:13