Cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

OAuth redirect not recognized by Fitbit app?

ANSWERED

Hi,

 

I'm desperately trying to implement OAuth. First and foremost: it works properly in the simulator, so basically I'd appreciate some insight what might be different in the real world.

 

After redirect, my website opens the following URL: https://app-settings.fitbitdevelopercontent.com/simple-redirect.html?code=12345&state=%7B%22callback...

 

However, the webpage stays white and nothing happens (see screenshot below). I've got some other apps and samples running where OAuth works fine on the same phone + device.

 

1. Yes, I do have internet access allowed and it's a HTTPS URL

2. Neither the `onAccessToken` nor `onReturn` functions of the `<Oauth />` react component are called.

3. Reboots, restarts, uninstalls also didn't fix it unfortunately.

 

Does anybody know how to fix this? 

 

 

 photo_2018-09-23_20-28-44.jpg

Best Answer
0 Votes
1 BEST ANSWER

Accepted Solutions

Okay, thanks to your https://app-settings.fitbitdevelopercontent.com/simple-redirect.html being available with source maps, I could debug your JS code and found out that the `state` parameter in the URL is invalid JSON. It looks like it's rather a problem of my server.

 

My server crops everything behind a `#` in the URL, which only happens on Android (and perhaps iOS), but not on my Windows environment due to the different formats of the callback URLs you generate for each platform.

Your simple-redirect.html then gets the state parameter, tries to parse it as JSON to extract the "callbackUrl" value. This fails because the JSON is invalid (there's no closing string and no } at the end because it's cropped), so it uses the `{"callbackUrl": "fitbit://someintent` directly and tries to launch this URI - which obviously fails as it's no valid URI.

 

Thanks for your help though!

 

PS: the whole https://app-settings.fitbitdevelopercontent.com application has public source maps. I'm not sure if you really want to open source this? 😉 

View best answer in original post

Best Answer
0 Votes
8 REPLIES 8

Which Model/OS/Version is your phone?

Best Answer
0 Votes
Google Pixel 1 with latest public Android 9.
Best Answer
0 Votes

are you able to share your companion and settings code, excluding any private keys

Best Answer
0 Votes

The companion doesn't do anything with the settings yet, so it's the following code only:

 

While thinking of it, perhaps it's because I set the client and URLs via React? I'm trying to authenticate with IndieAuth, which is on top of OAuth 2. Not sure how you're dealing with this internally, maybe there's a workaround I can use to get it working?

 

function mySettings(props) {
  return (
    <Page>
      <Section
        title={<Text bold align="center">Connection</Text>}>

        <TextInput
          label="URL"
          value={props.settings.url}
          onChange={value => {
            let url = value.name;
            
            if (url.length > 0 && url.substr(url.length - 1, 1) === "/") {
              url = url.substr(0, url.length - 1);
            }

            props.settingsStorage.setItem('url', url);
          }}
          placeholder="https://your-instance.com"
        />

        <Oauth
          settingsKey="oauth"
          title="OAuth Login"
          label="OAuth"
          status="Login"
          disabled={props.settingsStorage.getItem('url') == null}
          authorizeUrl={`${props.settingsStorage.getItem('url')}/auth/authorize`}
          requestTokenUrl={`${props.settingsStorage.getItem('url')}/auth/token`}
          clientId="todo"
        />
        
        </Section>
    </Page>
  );
}

registerSettingsPage(mySettings);
Best Answer
0 Votes

Okay, thanks to your https://app-settings.fitbitdevelopercontent.com/simple-redirect.html being available with source maps, I could debug your JS code and found out that the `state` parameter in the URL is invalid JSON. It looks like it's rather a problem of my server.

 

My server crops everything behind a `#` in the URL, which only happens on Android (and perhaps iOS), but not on my Windows environment due to the different formats of the callback URLs you generate for each platform.

Your simple-redirect.html then gets the state parameter, tries to parse it as JSON to extract the "callbackUrl" value. This fails because the JSON is invalid (there's no closing string and no } at the end because it's cropped), so it uses the `{"callbackUrl": "fitbit://someintent` directly and tries to launch this URI - which obviously fails as it's no valid URI.

 

Thanks for your help though!

 

PS: the whole https://app-settings.fitbitdevelopercontent.com application has public source maps. I'm not sure if you really want to open source this? 😉 

Best Answer
0 Votes

Can you please let me know what fix you did at server side. I am stuck, when I am using android device.

Best Answer

Hello can you please let me know the fix what you fixed on server side?

Best Answer
0 Votes

In my specific case it was a bug in a server side project I used - I don't have any insights in how it was fixed specifically but I can tell you what I experienced. 

 

When it was called with a redirect URI like "http://localhost/test#abc", then it only redirected to "http://localhost/test" and cropped the fragment. The fragment contains the OAuth token, so cropping it is no good idea.

I'm not sure whether you have the same problem, but for debugging I inspected the outgoing forward response and could see that the fragment was missing. Inspecting only the response of the URL which should be called with the fragment might not help as servers don't receive the fragment in the HTTP request URL - it stays in the browser only for security reasons (that's why the OAuth token is no GET query but in the fragment).

Best Answer
0 Votes