06-13-2015 08:30 - edited 06-14-2015 05:05
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post

SunsetRunner
06-13-2015 08:30 - edited 06-14-2015 05:05
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
When I get my accessToken I try to GET request it with the following code and get returned
WWWForm form = new WWWForm(); var headers = new Dictionary<string, string>(); headers["GET"] = "https://www.fitbit.com/oauth2/authorize"; headers["Authorization"] = "Bearer " + token; var getter = new WWW("https://api.fitbit.com/1/user/-/profile.json", null, headers);
I get my token back as
c011d387c0f96dcea307ab2ec5bb33193f10c6fe
{"errors":[{"errorType":"oauth","fieldName":"access_token","message":"Access token invalid or expired: c011d387c0f96dcea307ab2ec5bb33193f10c6fe"}],"success":false}
I can't figure out what's going on to make it wrong, it's about 1 second after getting the Token so it can't be expired
EDIT: Also, I've come across several threads asking about an easier way to integrate OAuth and Mobile (seems that you can't do a custom redirect_uri scheme like in a lot of the big names like Facebook and such). There was a lot of "we're working on an SDK" but I haven't come across it explicitly yet.
Is there an sdk BY Fitbit? A thing that would be super handy is a Unity SDK like what FB has done
https://developers.facebook.com/docs/unity
Answered! Go to the Best Answer.
Accepted Solutions
06-14-2015 13:12
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post



06-14-2015 13:12
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
@SunsetRunner wrote:
When I get my accessToken I try to GET request it with the following code and get returned
WWWForm form = new WWWForm(); var headers = new Dictionary<string, string>(); headers["GET"] = "https://www.fitbit.com/oauth2/authorize"; headers["Authorization"] = "Bearer " + token; var getter = new WWW("https://api.fitbit.com/1/user/-/profile.json", null, headers);I get my token back as
c011d387c0f96dcea307ab2ec5bb33193f10c6fe
{"errors":[{"errorType":"oauth","fieldName":"access_token","message":"Access token invalid or expired: c011d387c0f96dcea307ab2ec5bb33193f10c6fe"}],"success":false}
I can't figure out what's going on to make it wrong, it's about 1 second after getting the Token so it can't be expired
That's not a valid OAuth 2.0 access token. OAuth 2.0 access tokens use the JWT format. So the error is correct.
@SunsetRunner wrote:
EDIT: Also, I've come across several threads asking about an easier way to integrate OAuth and Mobile (seems that you can't do a custom redirect_uri scheme like in a lot of the big names like Facebook and such). There was a lot of "we're working on an SDK" but I haven't come across it explicitly yet.
Is there an sdk BY Fitbit? A thing that would be super handy is a Unity SDK like what FB has done
https://developers.facebook.com/docs/unity
No, there is no SDK by Fitbit. We've created a standard OAuth 1.0a and OAuth 2.0 Web API. This allows you to use generic OAuth 1.0a and OAuth 2.0 client libraries.
Also, we do support app protocols for callback redirect URIs. (We currently have a bug that don't allow hyphens in the protocol, e.g. my-app:// should be valid but isn't recognized as such yet. myapp:// would work.)

06-14-2015 13:12
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post



06-14-2015 13:12
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
@SunsetRunner wrote:
When I get my accessToken I try to GET request it with the following code and get returned
WWWForm form = new WWWForm(); var headers = new Dictionary<string, string>(); headers["GET"] = "https://www.fitbit.com/oauth2/authorize"; headers["Authorization"] = "Bearer " + token; var getter = new WWW("https://api.fitbit.com/1/user/-/profile.json", null, headers);I get my token back as
c011d387c0f96dcea307ab2ec5bb33193f10c6fe
{"errors":[{"errorType":"oauth","fieldName":"access_token","message":"Access token invalid or expired: c011d387c0f96dcea307ab2ec5bb33193f10c6fe"}],"success":false}
I can't figure out what's going on to make it wrong, it's about 1 second after getting the Token so it can't be expired
That's not a valid OAuth 2.0 access token. OAuth 2.0 access tokens use the JWT format. So the error is correct.
@SunsetRunner wrote:
EDIT: Also, I've come across several threads asking about an easier way to integrate OAuth and Mobile (seems that you can't do a custom redirect_uri scheme like in a lot of the big names like Facebook and such). There was a lot of "we're working on an SDK" but I haven't come across it explicitly yet.
Is there an sdk BY Fitbit? A thing that would be super handy is a Unity SDK like what FB has done
https://developers.facebook.com/docs/unity
No, there is no SDK by Fitbit. We've created a standard OAuth 1.0a and OAuth 2.0 Web API. This allows you to use generic OAuth 1.0a and OAuth 2.0 client libraries.
Also, we do support app protocols for callback redirect URIs. (We currently have a bug that don't allow hyphens in the protocol, e.g. my-app:// should be valid but isn't recognized as such yet. myapp:// would work.)

06-15-2015 13:55
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post

SunsetRunner
06-15-2015 13:55
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
Hmm, well I was trying to do it the way that is described in a few android instances and their uri's start with com.companyname.packagename (or flipped package/company) which the api wouldn't let me put in. (as far as I can understand the mobile should detect that uri when Fitbit redirects and then be able to catch stuff..but I haven't done native android either..)
I'm still a bit noobish when it comes to the web stuff as I usually just make PC/games/game logic 😛
So what is that "token" that I'm getting and passing to the form? Cause that's the kind of token that is being returned when the user hits allow for me.
Maybe it's just me misunderstanding the flow of OAuth but I thought it was you send the user to that page that says this app wants these permissions, they say yes or no.
If Yes, redirect_uri with the fitbit?code=bunchOfLettersAndNumbers
The code is the token to do the access token request right?
With that I'm supposed to do the Basic + Token (or code which ever lingo is right) POST to
https://www.fitbit.com/oauth2/authorize
and I guess it's then supposed to return the full on access token with which we can start doing requests via GET instead of POST?

06-15-2015 15:12
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post



06-15-2015 15:12
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
When you receive the code appended to your callback (redirect), you need to exchange it using the https://api.fitbit.com/oauth2/token endpoint. See "Access Token Request" section at https://wiki.fitbit.com/display/API/OAuth+2.0
Then you can make GET or POST requests to whatever API endpoints you want.

06-15-2015 15:58 - edited 06-15-2015 16:20
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post

SunsetRunner
06-15-2015 15:58 - edited 06-15-2015 16:20
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
But that's what I was trying to do in the original post of this thread?
I don't understand what I'm doing wrong in that step to not get the access token itself.
Like what is the
client_id=22942C&grant_type=authorization_code&redirect_uri=http%3A%2F%2Fexample.com%2Fcallback&code=1234567890
part of it? Is that just supposed to be in the data I send (not in the headers) or is that supposed to be appended to the endpoint?
I had changed the url I was sending it to after I dug around as well so the stuff I have now is
WWWForm form = new WWWForm(); form.headers["POST"] = "https://api.fitbit.com/oauth2/token"; form.headers["Authorization"] = "Basic " + token; form.headers["Content-Type"] = "application/x-www-form-urlencoded"; var getter = new WWW("https://api.fitbit.com/oauth2/token", null, form.headers);
EDIT:
(OR, this just occured to me, is that supposed to be the encoded part that goes into the application/x-www-form-urlencoded part? such as
client_id=MYID&grant_type=authorization_code&redirect_uri=http%3A%2F%2Fwww.travisevashkevich.com%2Ffitbit&code=
but what should I be putting in the code= spot in that case?)
should it be this
byte[] bytesToEncode =Encoding.UTF8.GetBytes("client_id=myClientID&grant_type=authorization_code&redirect_uri=http%3A%2F%2Fwww.travisevashkevich.com%2Ffitbit&code="+token); string encodedText = Convert.ToBase64String(bytesToEncode); WWWForm form = new WWWForm(); form.headers["POST"] = "https://api.fitbit.com/oauth2/token"; form.headers["Authorization"] = "Basic Y2xpZW50X2lkOmNsaWVudCBzZWNyZXQ="; form.headers["Content-Type"] = encodedText; var getter = new WWW("https://api.fitbit.com/oauth2/token", null, form.headers);

06-21-2015 04:05
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post

SunsetRunner
06-21-2015 04:05
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
Hey, I think I figured out another piece to this OAuth puzzle but I'm still not clear on one part of the documentation
Example
This example assumes that the code URI parameter value in the callback URI was 1234567890.
POST https://api.fitbit.com/oauth2/token Authorization: Basic Y2xpZW50X2lkOmNsaWVudCBzZWNyZXQ= Content-Type: application/x-www-form-urlencoded client_id=22942C&grant_type=authorization_code&redirect_uri=http%3A%2F%2Fexample.com%2Fcallback&code=1234567890
What am I supposed to do with the client_id part at the bottom. Is that supposed to just be tacked on to the https://api.fitbit.com/oauth2/token ?
I see what it is made up of but I just don't see what I'm supposd to do with it.
Also, the callback&code is the one we get back from the user doing allow, correct?

06-26-2015 11:43 - edited 06-26-2015 13:42
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post

06-26-2015 11:43 - edited 06-26-2015 13:42
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
Still trying to figure out what I'm supposed to fill in for a Unity POST call
I get
https://dl.dropboxusercontent.com/u/31340003/OAuth2Failing.png
as my return response headers
The 400 Bad Request is the error
var plainTextBytes = System.Text.Encoding.UTF8.GetBytes(_clientID + ";" + _consumerSecret); var encoded = Convert.ToBase64String(plainTextBytes); //make the content var content = "client_id=" + _clientID + "&grant_type=authorization_code&redirect_uri=" + CallBackUrl + "callback&code=" + _returnCode; var bytes = Encoding.ASCII.GetBytes(content); // next we will dothe authorization part of the OAuth2 var form = new WWWForm(); form.AddField("Authorization:", "Basic " + encoded); form.AddField("Content-Type:", "application/x-www-form-urlEncoded"); //form.AddField("Content: ", content); //form.AddField("Content-Length:", bytes.Length.ToString()); var response = new Dictionary<string, string>(); _statusMessage += "starting www /n"; bWWWRequest = true; _wwwRequest = new WWW("https://api.fitbit.com/oauth2/token", form.data, form.headers); StartCoroutine(WaitForAccess(_wwwRequest));
I've tried with the commented lines (in the addfield) and get the same Bad Request.
I have the feeling that I'm close I just can't figure out what I'm doing wrong...
Edit: Also I see that I posted under my actual account as well, just so you're aware I am the OP as well 🙂

06-29-2015 09:56
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post

06-29-2015 09:56
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
@TEvashkevich wrote:Still trying to figure out what I'm supposed to fill in for a Unity POST call
I get
https://dl.dropboxusercontent.com/u/31340003/OAuth2Failing.png
as my return response headers
The 400 Bad Request is the error
var plainTextBytes = System.Text.Encoding.UTF8.GetBytes(_clientID + ";" + _consumerSecret); var encoded = Convert.ToBase64String(plainTextBytes); //make the content var content = "client_id=" + _clientID + "&grant_type=authorization_code&redirect_uri=" + CallBackUrl + "callback&code=" + _returnCode; var bytes = Encoding.ASCII.GetBytes(content); // next we will dothe authorization part of the OAuth2 var form = new WWWForm(); form.AddField("Authorization:", "Basic " + encoded); form.AddField("Content-Type:", "application/x-www-form-urlEncoded"); //form.AddField("Content: ", content); //form.AddField("Content-Length:", bytes.Length.ToString()); var response = new Dictionary<string, string>(); _statusMessage += "starting www /n"; bWWWRequest = true; _wwwRequest = new WWW("https://api.fitbit.com/oauth2/token", form.data, form.headers); StartCoroutine(WaitForAccess(_wwwRequest));I've tried with the commented lines (in the addfield) and get the same Bad Request.
I have the feeling that I'm close I just can't figure out what I'm doing wrong...
Edit: Also I see that I posted under my actual account as well, just so you're aware I am the OP as well 🙂
OK, so Unity is C#-ish and you might want to take a look at our Fitbit.NET library branch with working OAuth 2.0 handshake here:
https://github.com/aarondcoleman/Fitbit.NET/blob/async-portable/Fitbit.Portable/Authenticator2.cs
One issue I see right off the bat is that you're using a semicolon ";" instead of a colon ":"
You might take some inspiration from this working* code. If you can get HttpClient and JSON.net working in Unity a lot of our library can be ported (minus the async stuff I believe)
public async Task<OAuth2AccessToken> ExchangeAuthCodeForAccessTokenAsync(string code)
{
HttpClient httpClient = new HttpClient();
string postUrl = FitbitApiBaseUrl;
postUrl += OAuthBase;
postUrl += "/token";
var content = new FormUrlEncodedContent(new[]
{
new KeyValuePair<string, string>("grant_type", "authorization_code"),
new KeyValuePair<string, string>("client_id", ClientId),
//new KeyValuePair<string, string>("client_secret", AppSecret),
new KeyValuePair<string, string>("code", code),
new KeyValuePair<string, string>("redirect_uri", this.RedirectUri)
});
string clientIdConcatSecret = Base64Encode(ClientId + ":" + AppSecret);
httpClient.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Basic", clientIdConcatSecret);
HttpResponseMessage response = await httpClient.PostAsync(postUrl, content);
string responseString = await response.Content.ReadAsStringAsync();
JObject responseObject = JObject.Parse(responseString);
// Note: if user cancels the auth process Fitbit returns a 200 response, but the JSON payload is way different.
var error = responseObject["error"];
if (error != null)
{
// TODO: Actually should probably raise an exception here maybe?
return null;
}
OAuth2AccessToken accessToken = new OAuth2AccessToken();
var temp_access_token = responseObject["access_token"];
if (temp_access_token != null) accessToken.Token = temp_access_token.ToString();
var temp_expires_in = responseObject["expires_in"];
if (temp_expires_in != null) accessToken.ExpiresIn = Convert.ToInt32(temp_expires_in.ToString());
var temp_token_type = responseObject["token_type"];
if (temp_token_type != null) accessToken.TokenType = temp_token_type.ToString();
var temp_refresh_token = responseObject["refresh_token"];
if (temp_refresh_token != null) accessToken.RefreshToken = temp_refresh_token.ToString();
return accessToken;
}
*"Works on my machine"


06-29-2015 16:26 - edited 06-29-2015 16:40
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post

06-29-2015 16:26 - edited 06-29-2015 16:40
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
Hey Aaron,
I was trying to get stuff working with your lib a few times and again tonight BUT I just found the problem after going through your code a few times.
Apparently I had to UNescape my redirect_uri. (I was pre-escaping it as in the examples it was always escaped)
On to the next step and hopefully the last 😄

