我目前正致力于按照此处描述的方法为Twitter合并授权功能:https://dev.twitter.com/docs/auth/implementing-sign-twitter。我正在使用Ajax发送我的POST'http'请求,但我一直遇到'401:Unauthorized'错误。我的代码如下:
function getTweets() {
var time = generateTimestamp();
var nonce = generateNonce();
var signature = generateSignature(time, nonce);
var headers = {
"Authorization": 'OAuth oauth_callback="http%3A%2F%2Fwww.google.com%2F", oauth_consumer_key="eEeAAz9fakedtAOlIUhPgQ", oauth_nonce="bbc34b2ca6faabogus6dfc025907fa334", oauth_signature="' + signature + '", oauth_signature_method="HMAC-SHA1", oauth_timestamp="' + time + '", oauth_version="1.0"'
};
$.ajax({
type: "POST",
url: "https://api.twitter.com/oauth/request_token",
dataType: "text",
headers: headers,
success: function(data) {
alert("Success!");
console.log(data);
},
error: function(jq) {
alert("Request Failed.");
console.log(jq.statusText);
}
});
}
function generateTimestamp() {
var currentTime = new Date;
currentTime = Math.floor(currentTime.getTime() / 1000);
return currentTime;
}
function generateNonce() {
var code = "";
for (var i = 0; i < 20; i++) {
code += Math.floor(Math.random() * 9).toString();
}
return code;
}
function generateSignature(timestamp, nonce) {
var http_method = "POST";
var base_url = "https://api.twitter.com/oauth/request_token";
var consumer_key = "eEeAAz9hUKtdjunkeIUhPgQ";
var consumer_secret = "c7wHxnjubxVDcc5hYFqnotactuallymysecretWs2XazUFde0lPRBtBQ";
var signature_method = "HMAC-SHA1";
var token = "609493744-kNPzLKSI4Hg9NWQnopeFPb91eXFUutFm1nZ2hDk2";
var token_secret = "15WOJS9Ji1AXsKRkyAZrxKdsalted5Gj5ZyEAb9aVrJxI";
var version = "1.0";
var parameter_string = "oauth_callback=" + encodeURIComponent(base_url) + "&oauth_consumer_key=" + consumer_key + "&oauth_nonce=" + nonce + "&oauth_consumer_key=" + consumer_key + "&oauth_signature_method=" + signature_method + "&oauth_timestamp=" + timestamp +"&oauth_version=" + version;
var base_string = http_method + "&" + encodeURIComponent(base_url) + "&" + encodeURIComponent(parameter_string);
var signing_key = encodeURIComponent(consumer_secret) + "&";
var signature = encodeURIComponent(window.btoa(CryptoJS.HmacSHA1(base_string, signing_key)));
alert(signature);
return signature;
}
如果有任何其他信息可以使此错误更清晰,请随时在下面发布。感谢。
答案 0 :(得分:0)
我创建了一个node.js库来搞乱Twitter OAuth舞蹈和API。代码为here, tweeter.js
欢迎您浏览创建标题和签名的逻辑(从348行开始)
我在您发布的代码中没有看到的一件事情会产生巨大差异,必须生成签名字符串以包含原始标题,然后标题必须重建使用生成的字符串。这是一个巨大的痛苦,我花了一段时间才弄明白。
虽然我编写的代码面向node.js,但您应该能够重用大量逻辑来满足您的需求。
修改强>
我发现一个名为hueniverse的网站很好地记录了OAuth。实际上,有一个实用程序here用于构建您自己的标头以验证您的逻辑(选择“创建您自己的”单选按钮)。
编辑2
为了更好地解释在标题中包含oauth_signature
值,假设您拥有到目前为止的所有数据:
var headerObj = {
oauth_consumer_key="123456789",
oauth_token="11111",
oauth_nonce="asdfghjkl%3B",
oauth_timestamp="1341852000",
oauth_signature_method="HMAC-SHA1",
oauth_version="1.0"
};
您创建HMAC-SHA1签名并接收:"jBpoONisOt5kFYOrQ5fHCSZBGkI%3D"
然后,您将该返回值添加到headerObj
,为您提供:
headerObj = {
oauth_consumer_key="123456789",
oauth_token="11111",
oauth_nonce="asdfghjkl%3B",
oauth_timestamp="1341852000",
oauth_signature_method="HMAC-SHA1",
oauth_version="1.0",
oauth_signature="jBpoONisOt5kFYOrQ5fHCSZBGkI%3D"
};
这个修改后的headerObj版本是您从。
构建HTTP标头的GET / HTTP/1.1
Host: api.twitter.com:443
Authorization: OAuth realm="https://api.twitter.com/",
oauth_consumer_key="123456789",
oauth_token="11111",
oauth_nonce="asdfghjkl%3B",
oauth_timestamp="1341852000",
oauth_signature_method="HMAC-SHA1",
oauth_version="1.0",
oauth_signature="jBpoONisOt5kFYOrQ5fHCSZBGkI%3D"
注意:我没有验证主机/域/端口,所以这些可能是错误的。检查API。
这样做的原因是在Twitter方面(这是一个OAuth实现细节),oauth_signature
值被删除,标题的其余部分被散列,其返回值与发送的值进行比较oauth_signature
。它有点像信封上的蜡封......如果标题其余部分的哈希值与您在oauth_signature
中发送的哈希值不匹配,则Twitter知道不信任发件人或内容。 / p>
编辑2.5
我正在将这一点从评论转移到答案。
如果你在tweeter.js中查看this line,你会看到逻辑。
var signature = self.oauthSignature(method, path, headerObj, query);
headerObj.oauth_signature = qs.escape(signature);
// concat the header object into a csv string
var header = 'OAuth realm="Twitter API",';
var oauthParts = [];
for (var h in headerObj) {
oauthParts.push(h + '="'+headerObj[h]+'"');
}
header+= oauthParts.join(',');
//...
return header;
我在编辑2中解释过这一段代码,通过将JSON对象转换为key="value"
中存储的oauthParts[]
字符串,然后将该数组中的每个元素连接成一个以逗号分隔的字符串以OAuth realm="Twitter API",