使用oauth签名发布数据时,Flickr API会抛出“无效的API密钥(密钥格式无效)”

时间:2014-09-28 20:12:57

标签: javascript node.js flickr

我似乎无法在任何地方找到这个答案,甚至谷歌 - 我对Flickr上传API进行了oouth签名调用,并且在the docs后我以通常的oauth方式签署了POST操作(但没有photo数据)。出于测试目的,我只传递了titlephoto数据,这意味着我最终得到一个var flickrURI,其中包含以下用于POST的网址:

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

(在这个问题中,由于显而易见的原因,实际的网址在?&附近没有任何空白,因此在多个行中分开可读性。

oauth签名本身是非常正确的,用于访问整个地方的非上传API的代码具有正确的行为,所以看起来几乎不可能让签名错误,除了可能签署“没有足够的数据“或者可能用”太多的数据“签名。

auth签名首先形成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令牌和秘密,因此包含的访问令牌和访问令牌秘密应该通过“此密钥的此令牌是否具有写入权限”测试。

我在这里遗漏了哪些阻止上传的事情?

2 个答案:

答案 0 :(得分:0)

您似乎正在使用https://up.flickr.com/services/upload/端点,该端点使用旧的身份验证方案。

对于OAuth,它应该是https://api.flickr.com/services/upload/。确保端点包含在签名过程中。

我不认为它记录在任何地方,但我记得有一段时间有同样的问题。

答案 1 :(得分:0)

事实证明,添加数据时request.post多部分信息不够好,并且会使Flickr API抛出一个&#34;无效的API密钥(密钥格式无效)&#34;错误,而不是说出实际上是错的。以下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]);
});

尽管没有那么明智地打电话明智(为什么在我们打电话给form = req.form()时尚未完成POST?)这是请求&#34;正确的&#34;通过网络发送POST有效负载的方法,并使Flickr API处理照片上传得很好。