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

3rd party REST API OAuth authentication

ANSWERED

I need to use the companion for handling the communication to 3rd party REST Web API.

I am able to perform the web requests (GET and POST) using fetch but for some of them the authentication is required.

I see that in Strava app, the user can click on Strava Login in settings area and an instance of the browser is opened on Strava authentication page.

As soon as the credentials are provided the user and - I guess 🙂 - a token are saved in companion settings. In this way I could avoid to store user and password directly in app settings.

How can I implement something similar?

Best Answer
0 Votes
1 BEST ANSWER

Accepted Solutions

As a workaround, you can handle the token request yourself.

 

  onReturn={async (data) => {
      console.log(JSON.stringify(data));
      getToken(data.code).then(function(result) {
        console.log(result);
        try {
            settingsStorage.setItem('access_token', result.access_token);
            settingsStorage.setItem('refresh_token', result.refresh_token);
            settingsStorage.setItem('genDateToken', new Date().toISOString());
        } catch(err) {
            console.log('Storage err: '+ err);
        }
      }).catch(function(err){
        console.log('Err: '+ err);
      })
  }}

 

 

async function getToken(exchangeCode) {
    const urlEncodePost = function (object) {
        let fBody = [];
        for (let prop in object) {
            let key = encodeURIComponent(prop);
            let value = encodeURIComponent(object[prop]);
            fBody.push(key + "=" + value);
        }
        fBody = fBody.join("&");
        return fBody;
    };
// https://dev.fitbit.com/reference/web-api/oauth2/#authorization-header const Token_Body = { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded',
'Authorization': 'Basic XXXXXX' }, body: urlEncodePost({ grant_type: 'authorization_code', client_id: "xxxxxx", client_secret: "xxxxxx", code: exchangeCode, redirect_uri:'https://app-settings.fitbitdevelopercontent.com/simple-redirect.html', }) }; return await fetch('xxxxxxxx', Token_Body) .then(function(data){ return data.json(); }).catch(function(err) { console.log('Err on token gen '+ err); }) }

 

 

 

 

View best answer in original post

Best Answer
8 REPLIES 8
Best Answer

There is also a sample app which shows how to use OAuth. https://github.com/Fitbit/sdk-oauth

Best Answer
0 Votes

I am able to perform the login operation for 3rd party web API using OAuth button but it does not work properly every time.

Sometimes it works as expected, storing inside the setting key the access token.
Sometimes it fails.

I've attached the onAccessToken callback to OAuth button

onAccessToken={async (data) => {

   console.log(data);

}}


and when the token retrieving fails, it logs the following error
{ error = "invalid_grant"; "error_description" = "Invalid authorization code"; }

Investigating server side on this issue we found that after the retrieving of authorization code (from authorizeUrl) the fitbit app calls  2 times the token exchange request using requestTokenUrl.

It looks pretty strange because my expectation is to receive just one token exchange request.


I see the following pattern:
if the first request has success and the second has failure then the token is retrieved properly.
if the first request has failure and the second has success then the token is not retrieved and I see the "invalid_grant" error.

Best Answer
0 Votes

I can confirm the invalid grant behavior in my app. It makes refreshing tokens very precarious.  The occasional double-call would explain why it's been difficult to diagnose.

 

Can you elaborate as to what "investigating server side" means?

Best Answer
0 Votes

Fortunately I have access to the Auth0 service that it is handling the authentication request.

Taking a look at the Auth0 logs, I have found the double requests.

 

This problem is present only on iOS. I have just tried on Android and the authentication is working fine and I see only one token exchange request on Auth0 logs (as expected).

It looks definitely like a fitbit app for iOS bug.

Best Answer
0 Votes

As a workaround, you can handle the token request yourself.

 

  onReturn={async (data) => {
      console.log(JSON.stringify(data));
      getToken(data.code).then(function(result) {
        console.log(result);
        try {
            settingsStorage.setItem('access_token', result.access_token);
            settingsStorage.setItem('refresh_token', result.refresh_token);
            settingsStorage.setItem('genDateToken', new Date().toISOString());
        } catch(err) {
            console.log('Storage err: '+ err);
        }
      }).catch(function(err){
        console.log('Err: '+ err);
      })
  }}

 

 

async function getToken(exchangeCode) {
    const urlEncodePost = function (object) {
        let fBody = [];
        for (let prop in object) {
            let key = encodeURIComponent(prop);
            let value = encodeURIComponent(object[prop]);
            fBody.push(key + "=" + value);
        }
        fBody = fBody.join("&");
        return fBody;
    };
// https://dev.fitbit.com/reference/web-api/oauth2/#authorization-header const Token_Body = { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded',
'Authorization': 'Basic XXXXXX' }, body: urlEncodePost({ grant_type: 'authorization_code', client_id: "xxxxxx", client_secret: "xxxxxx", code: exchangeCode, redirect_uri:'https://app-settings.fitbitdevelopercontent.com/simple-redirect.html', }) }; return await fetch('xxxxxxxx', Token_Body) .then(function(data){ return data.json(); }).catch(function(err) { console.log('Err on token gen '+ err); }) }

 

 

 

 

Best Answer

Has this issue been resolved yet?

Best Answer
0 Votes

Hello there,

 

I have same issue. I haven't been able to get redirected back to settings page on clockface app on fitbit app on redirection from a third party oauth2 provider. It always redirects to "

https://app-settings.fitbitdevelopercontent.com/simple-redirect.html" but am not getting control back to the Fitbit app setting page. I am using Fitbit provided oauth button from Setting API. Please help. thank you

 

<Oauth
settingsKey="oauth"
align="center"
title="Login"
status="Login"
authorizeUrl="https://sandbox-api.example.com/v1/oauth2/login"
requestTokenUrl="https://sandbox-api.example.com/v1/oauth2/token"
response_type="code"
clientId="<removed>"
clientSecret="<removed>"
grant_type="authorization_code"
scope="offline_access"
state="Test by Sri"
/>

Best Answer
0 Votes