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?
Answered! Go to the Best Answer.
Best Answer
Fitbit Developers oversee the SDK and API forums. We're here to answer questions about Fitbit developer tools, assist with projects, and make sure your voice is heard by the development team.
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);
})
}
I found the answer here
https://dev.fitbit.com/reference/settings-api/#oauth-button
https://dev.fitbit.com/reference/settings-api/#strava-login-button
I'll do some experiments and I'll let you know my findings
Fitbit Developers oversee the SDK and API forums. We're here to answer questions about Fitbit developer tools, assist with projects, and make sure your voice is heard by the development team.
There is also a sample app which shows how to use OAuth. https://github.com/Fitbit/sdk-oauth
Best AnswerI 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 AnswerI 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 AnswerFortunately 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
Fitbit Developers oversee the SDK and API forums. We're here to answer questions about Fitbit developer tools, assist with projects, and make sure your voice is heard by the development team.
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);
})
}
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