Fitbit OAuth API请求,签名无效

时间:2015-08-09 20:01:08

标签: javascript node.js api oauth

我正在尝试使用fitbit(https://dev.fitbit.com/apps/oauthtutorialpage)的oauth调试器向fitbit发出API请求,我试图弄清楚我做错了什么。我在下面的代码中添加了注释,以帮助您了解我想要实现的目标。我非常确定的是,我要么错误地签署我的请求,要么使用错误的数据签名。这得到了API响应的响应。

我知道stackoverflow上有更多的fitbit api问题,但是没有找到我的答案。

是否有人在Oauth签名方面有更多经验,知道我可能做错了什么?或者可以帮我找到一个不同的方法吗?

var request = require('request');
var crypto = require('crypto');

var params = {
    'oauth_consumer_key' : 'key12345',
    'oauth_nonce' : Math.random().toString(36).substring(3), //random string
    'oauth_signature_method' : 'HMAC-SHA1',
    'oauth_timestamp' : Date.now().toString().substring(0,10), //timestamp with the same length as in the tutorial
    'oauth_version' : '1.0'
}
var oauth_consumer_secret = 'secret123';
var post_string = 'POST&https://api.fitbit.com/oauth/request_token';

for(var key in params){
    post_string += '&' + key + '=' + params[key];
}

/*At this point we have made a post string that we have to hash with hmac-sha1
the post string looks like this:
POST&https://api.fitbit.com/oauth/request_token&oauth_consumer_key=key12345&oauth_nonce=az6r8cqlzyqfr&oauth_signature_method=HMAC-SHA1&oauth_timestamp=1439147378&oauth_version=1.0

The post_string from the tutorial looks like this:
POST&%2Foauth%2Frequest_token&oauth_consumer_key%3D%26oauth_nonce%3D%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1439145944%26oauth_version%3D1.0

*/

var hmac = crypto.createHmac('sha1', oauth_consumer_secret + "&");
// The tutorial page shows me the signature was 'signed with secret&'. I have tried with and without the & at the end, but without luck.
hmac.setEncoding('base64'); //i'm not sure if this is correct
hmac.write(post_string);
hmac.end();
var hash = hmac.read();

//and finally adding the hash to the parameters.
params.oauth_signature = hash; 

//now, making the request with an authorization header.
var header='';
for (var key in params){
    if(header.length === 0){
        header = ' OAuth ' + key + '="' + params[key] + '"';
    }
    else{
        header += ', ' + key + '="' + params[key] + '"';
    }
}

/*
At this point the header parameter looks like this

OAuth oauth_consumer_key="key12345", oauth_nonce="jnr97ppvjs2lnmi", oauth_signature_method="HMAC-SHA1", oauth_timestamp="1439148049", oauth_version="1.0", oauth_signature="random_signature"   

The tutorial tells me to use the headers:
OAuth oauth_consumer_key="key12345", oauth_nonce="jnr97ppvjs2lnmi", oauth_signature="different_signature", oauth_signature_method="HMAC-SHA1", oauth_timestamp="1439145944", oauth_version="1.0"
*/

var headers ={
    'Authorization' : header
}

var url="https://api.fitbit.com/oauth/request_token";
var requestTimeout = 5000;
var opts = {
    url: url,
    timeout: requestTimeout,
    headers : headers
}

request(opts, function (err, res, body) {
    if (err) {
        console.dir(err);
        return;
    }
    var statusCode = res.statusCode;
    if(res.statusCode === 200){
         console.log(body);
    }
    else{
        console.log("http-error-code: " + res.statusCode);
        console.log(body);
    }
})
/*
The response: 
http-error-code: 401
{"errors":[{"errorType":"oauth","fieldName":"oauth_signature","message":"Invalid signature: 9fXI85C7GvZqMyW1AK1EkOSWZCY="}],"success":false}
*/

1 个答案:

答案 0 :(得分:1)

要获取访问令牌和秘密使用Grant(您可以在playground中测试FitBit。)

一旦您拥有访问令牌并秘密使用Purest来向FitBit API发出后续请求。

以下是如何获取用户个人资料的示例:

byte[]

或者您可以使用请求:

char[]

简而言之 - 请勿尝试自行实施网络服务器OAuth流程 - 使用Grant,然后使用Purest或请求,请记住,您不必通过所有OAuth参数都由您自己完成,只需传递凭据即可。