5

I'm trying to connect to the fitbit api using the httr library.

Using the examples provided, I came up with the following code:

library(httr)

key <- '<edited>'
secret <- '<edited>'
tokenURL <- 'http://api.fitbit.com/oauth/request_token'
accessTokenURL <- 'http://api.fitbit.com/oauth/access_token'
authorizeURL <- 'https://www.fitbit.com/oauth/authorize'

fbr <- oauth_app('fitbitR',key,secret)
fitbit <- oauth_endpoint(tokenURL,authorizeURL,accessTokenURL)

token <- oauth1.0_token(fitbit,fbr)
sig <- sign_oauth1.0(fbr,
    token=token$oauth_token,
    token_secret=token$oauth_token_secret
)

I get the Authentication complete. message from httr, but trying to access the api then throws an error message

GET("http://api.fitbit.com/1/user/-/activities/date/2012-08-29.json", sig)
Response [http://api.fitbit.com/1/user/-/activities/date/2012-08-29.json]
  Status: 401
  Content-type: application/x-www-form-urlencoded;charset=UTF-8
{"errors":[{"errorType":"oauth","fieldName":"oauth_access_token","message":"Invalid signature or token '<edited>' or token '<edited>'"}]} 

Any clue about what the problem might be?

csgillespie
  • 59,189
  • 14
  • 150
  • 185
Yann Abraham
  • 330
  • 3
  • 11

2 Answers2

3

The problem comes from the httr library, that uses curlEscape for encoding paramaters while the OAuth 1.0 specifications requires percent encoding (see this page).

Replacing calls to curlEscape with curlPercentEncode solves the issue!

many thanks to @mark-s for his help.

Yann Abraham
  • 330
  • 3
  • 11
  • 1
    Could you please expand the answer by giving an example code of how to "replace call to curlEscape with curlPercentEncode"? – Crt Ahlin Aug 06 '15 at 05:06
  • Would you care to explain what this means? (Although I'm not sure if that's still relevant since implementation of `httr` seems to have changed). – Verena Haunschmid Sep 17 '16 at 14:36
2

The only thing I notice is that your call to get the signature is slightly different than the httr examples. The httr examples are:

sig <- sign_oauth1.0(myapp, token$oauth_token, token$oauth_token_secret)

While your code is:

sig <- sign_oauth1.0(fbr,
    token=token$oauth_token,
    token_secret=token$oauth_token_secret
)

Do you need the "token=" and "token_secret=" in your code?

Mark S.
  • 3,849
  • 4
  • 20
  • 22
  • 1
    Just tried for the sake of it, but it made no difference: anyway, using named arguments should not make a difference? But thanks for your suggestion! – Yann Abraham Aug 31 '12 at 16:30
  • Can you post the verbose request with the headers included? – Mark S. Aug 31 '12 at 16:43
  • Here is the http header: OAuth oauth%5Fconsumer%5Fkey=\"\", oauth%5Fnonce=\"ImkQ6g3HO0\", oauth%5Fsignature=\"\", oauth%5Fsignature%5Fmethod=\"HMAC%2DSHA1\", oauth%5Ftimestamp=\"1346655744\", oauth%5Ftoken=\"\", oauth%5Fversion=\"1%2E0\" does this help? – Yann Abraham Sep 03 '12 at 07:20
  • I forgot to mention I'm sitting behind a proxy: although I tried it on a different computer and got the same problem, could this be a reason? – Yann Abraham Sep 03 '12 at 07:35
  • after much looking around it turns out that the oauth_signature was the problem (as was indeed reported by the API) - see my answer below – Yann Abraham Sep 03 '12 at 08:55