10-08-2014 07:06
10-08-2014 07:06
I have been able to successfully authenticate users, however, whenever I make a POST request I am getting a 401 response. I am not reauthenticating the user. If I send a GET request to view the user's profile I get a successful response. However (with the same credentials) if I send a POST request to update the user's profile I get a 401. My application has been set up with "Read & Write Access Type.
Can someone help?
10-08-2014 07:45
10-08-2014 07:45
Hello,
What the response body says?
It should provide to you information why it giving back 401 for you.
10-08-2014 08:06
10-08-2014 08:06
I get the following response:
{"errors":[{"errorType":"oauth","fieldName":"oauth_signature","message":"Invalid signature: xqsK/Du9FP6k98lQDHLk2kbSrCY="}],"success":false}
I am creating the signature the same way I do when using a GET request. Is that incorrect?
Thanks!
10-08-2014 08:20 - edited 10-08-2014 08:20
10-08-2014 08:20 - edited 10-08-2014 08:20
Invalid signature means you are not signing your POST request properly, this is the only reason why you are getting back 401 with
Invalid signature:
response, even though you may be convinced you're doing it the same way you do it for GET request, there must be an error in your signature generation.
Please check out Fitbit Oauth 1.0a debug tool and compare the values that are generated by this tool and what is your code generating, signatures as well as base string should be the same:
https://dev.fitbit.com/apps/oauthtutorialpage
Also for more information about signing requests check out this wiki page:
https://wiki.fitbit.com/display/API/OAuth+Authentication+in+the+Fitbit+API
10-28-2014 14:59
10-28-2014 14:59
I have used that excellent API testing tool and got the user authentication and permanent token thing working. For a while we had the getActivities (and other APIs) working as well, but suddenly today they no longer work. We are calling http://api.fitbit.com/1/user/-/activities/date/2014-10-28.json.
I am getting this back:
exception 'FitBitException' with message 'Fitbit request failed. Code: 401' in fitbitphp.php:470 Stack trace: #0 application\models\participant_model.php(1829): FitBitPHP->getActivities(Object(DateTime)) #1
The oath return info says this:
lArray ( [http_code] => 401 [content_type] => application/json;charset=UTF-8 [url] => http://api.fitbit.com/1/user/-/activities/date/2014-10-28.json [header_size] => 518 [request_size] => 424 [filetime] => -1 [ssl_verify_result] => 0 [redirect_count] => 0 [total_time] => 0.125 [namelookup_time] => 0 [connect_time] => 0.031 [pretransfer_time] => 0.031 [size_upload] => 0 [size_download] => 197 [speed_download] => 1576 [speed_upload] => 0 [download_content_length] => 197 [upload_content_length] => 0 [starttransfer_time] => 0.125 [redirect_time] => 0 [headers_recv] => HTTP/1.1 401 Unauthorized Server: nginx X-UA-Compatible: IE=edge,chrome=1 Expires: Thu, 01 Jan 1970 00:00:00 GMT Cache-control: no-cache, must-revalidate Pragma: no-cache Set-Cookie: JSESSIONID=79BF1D4CF00DC28359569CB3EE351DE3.fitbit1; Path=/; HttpOnly WWW-Authenticate: OAuth realm="http%3A%2F%2Fapi006-g4.prod.dal05.fitbit.com" Content-Type: application/json;charset=UTF-8 Content-Language: en Content-Length: 197 Vary: Accept-Encoding Date: Tue, 28 Oct 2014 21:22:12 GMT X-Frame-Options: SAMEORIGIN )
10-28-2014 15:02
10-28-2014 15:02
Take a look at the body of the HTTP response, it should provide more information on the error.
10-28-2014 15:12 - edited 10-28-2014 15:24
10-28-2014 15:12 - edited 10-28-2014 15:24
Body says
{"errors":[{"errorType":"oauth","fieldName":"oauth_access_token","message":"Invalid signature or token 'EOAUuNwUyOHzlm9qYJpOeLDmdH8=' or token '4b7915b8a41f39ded2b800f051f450ec'"}],"success":false}
I notice the secret token has letters like u and r in it, is it only supposed to be hexadecimal? The oauth tool says the signature is correct.
Hey, I just noticed that I get three different signatures as this process goes through, and only the second one generated by getRequestHeader matches the one produced by the fitbit oauth tool. Fetch returns a third signature that comes from somewhere else, not sure where that might be.
echo "header start:";
print_r($headers);
echo "header end";
echo "signature:";
print_r($this->oauth->generateSignature ( "GET" , $targeturl));
echo "signature end";
echo "start encoded";
print_r($this->oauth->getRequestHeader ( 'GET' ,$targeturl));
echo "end encoded<br>";
echo $targeturl;
try {
$this->oauth->fetch($targeturl,null, OAUTH_HTTP_METHOD_GET);
10-28-2014 15:14
10-28-2014 15:14
As I astated above, if you get message:
"Invalid signature or token ..."
that means only one of two possible things, either signature is invalid or token is invalid.
There is no other posible issues can be when you get such response.
Please try to debug it with fitbit debug tool: https://dev.fitbit.com/apps/oauthtutorialpage
10-28-2014 15:38
10-28-2014 15:38
OK, I discovered why the signatures were changing - PHP generates a new nonce every time you call something unless you set it with oauth->setNonce(). Now all three calls match the signature generated by the tool at https://dev.fitbit.com/apps/oauthtutorialpage, so by the above I must conclude that the tokens are wrong. Is there any way to verify that a token is correct? I just barely got these new tokens in response to user registration requests several hours ago.
10-28-2014 15:41 - edited 10-28-2014 15:43
10-28-2014 15:41 - edited 10-28-2014 15:43
https://dev.fitbit.com/apps/oauthtutorialpage page generates to you CURLs that you can run from comand line and see the response from Fitbit.
This was you can test if you getting good response from Fitbit API.
10-28-2014 16:16
10-28-2014 16:16
@DevDave wrote:
OK, I discovered why the signatures were changing - PHP generates a new nonce every time you call something unless you set it with oauth->setNonce(). Now all three calls match the signature generated by the tool at https://dev.fitbit.com/apps/oauthtutorialpage, so by the above I must conclude that the tokens are wrong. Is there any way to verify that a token is correct? I just barely got these new tokens in response to user registration requests several hours ago.
The tokens are valid indefinitely, except in the following cases:
1. You send the user through the OAuth flow again and that issues a new token and invalidates the old token
2. The user revokes your application from accessing their data (https://www.fitbit.com/user/profile/apps)
I'm going to guess that its case #1?
10-28-2014 16:46 - edited 10-28-2014 16:49
10-28-2014 16:46 - edited 10-28-2014 16:49
Definitely not number 2, since I am the user 🙂
But number 1 is unlikely as well, since I only call the token grabber when the database has no user:secret stored, and once it is there the only fitbit interaction is
$tokenparts = explode(":",trim($pdata[0]['fitbittoken']));
// make all 5 calls
$fitbitrequest = new FitBitPHP("2062a3e3991440979b9d335ebc31b03c", "secret I changed for this post"); //$consumer_key, $consumer_secret
$fitbitrequest->setOAuthDetails($tokenparts[0], $tokenparts[1]);
$today = date('n/j/Y',time());
try
{
$goaldata = array();
$dt = new DateTime($today);
$goaldata['activities'] = $fitbitrequest->getActivities($dt);//date in format yyyy-MM-dd.
So is there a way to see if I have a correct token in the fitbit database? This was working fine last week, just suddenly broke this week.
Oh, here's how I respond to the permanent token request:
$token = GetRequestString("oauth_token");
$secret = GetRequestString("oauth_verifier");
ExecQuery("update eligible set fitbittoken = '".$token.":".$secret."' where entity_id = '".$eid."'");
10-28-2014 17:17
10-28-2014 17:17
Requesting new token will solve the problem for sure in this case.
10-28-2014 18:01
10-28-2014 18:01
I thought so as well, but I tried it three times and no luck. I am getting a new token each time, and I ensure that I only call initSession when the fitbit_token field is NULL.
10-28-2014 18:05
10-28-2014 18:05
@DevDave wrote:
So is there a way to see if I have a correct token in the fitbit database? This was working fine last week, just suddenly broke this week.
If you private message me your account email and the oauth user token, I can check for you.
10-30-2014 14:34
10-30-2014 14:34
Victory! I got the tokens working again! The original test scenario that was working before had been established outside the current flow, so it was wrong that our current configuration was good. For those who want to verify that things are as they think they are, you should make sure that both pieces of initSession are being called (php solution) by writing the tokens to a file. Also, the verifier that is returned to your callbackURL is wrong, use the one that is retrieved by the actual call:
if ($_SESSION['fitbit_Session'] == 0) {
$request_token_info = $this->oauth->getRequestToken($this->requestTokenUrl, $callbackUrl);
$_SESSION['fitbit_Secret'] = $request_token_info['oauth_token_secret'];
$_SESSION['fitbit_Session'] = 1;
header('Location: ' . $this->authUrl . '?oauth_token=' . $request_token_info['oauth_token']);
$_SESSION['fitbit_Token'] = $request_token_info['oauth_token'];
$fd = fopen("temptoken.txt","a+");
fwrite($fd, "stage1 : ".$request_token_info['oauth_token_secret']." : ".$request_token_info['oauth_token']."\r\n".$callbackUrl."\r\n");
fclose($fd);
return 0;
} else if ($_SESSION['fitbit_Session'] == 1) {
$this->oauth->setToken($_SESSION['fitbit_Token'], $_SESSION['fitbit_Secret']);
$access_token_info = $this->oauth->getAccessToken($this->accessTokenUrl);
$_SESSION['fitbit_Session'] = 2;
$_SESSION['fitbit_Token'] = $access_token_info['oauth_token'];
$_SESSION['fitbit_Secret'] = $access_token_info['oauth_token_secret'];
$this->setOAuthDetails($_SESSION['fitbit_Token'], $_SESSION['fitbit_Secret']);
$fd = fopen("temptoken","a+");
fwrite($fd, "stage2 : ".$_SESSION['fitbit_Token']." : ".$_SESSION['fitbit_Secret']);
fclose($fd);
return 1;