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

OAuth Button error: Invalid callback url

I am using the OAuth Button to authenticate with the Spotify Web API using the OAuth 2.0 authorization code flow.

 

Here is my OAuth Button JSX:

<Oauth
    settingsKey="oauth"
    title="Spotify Login"
    label="Spotify"
    status="Login"
    authorizeUrl="https://accounts.spotify.com/authorize"
    requestTokenUrl="https://accounts.spotify.com/api/token"
    clientId="---redacted---"
    clientSecret="---redacted---"
    scope="user-modify-playback-state user-read-playback-state user-library-read user-library-modifyprofile"
    onAccessToken={async (data) => {
        console.log(`Settings: Auth succeeded?`);
        console.log(data);
        console.log(JSON.stringify(data));
    }}
/>

 

The redirect from Spotify's authorization page looks like:

https://app-settings.fitbitdevelopercontent.com/simple-redirect.html?code=AQA0WSZ4dm2PIBZK7ELcG4nuc-mLhd5T7RaHhOZ28kPMtq1up3vUhFLlWfA-Ngo89-DW4SdTt5c9h4zB4wo0duz86Cr6V13Ke9qTxs1zx905EEO3TX_VAtaJJqwDit4JwE7wFy7GnEii-gzOuDNrWrhwd35gq7OyTZj7d8fCfo-hhvGw1M4kZb083YryEScROu2zF9wOv44PeNaNFp1bAWx9o4CuGTR_zeLWklJqYGYhXOzjyIldjtC-F2iYG9-ZJxztsbC6bWX5IP443kDqLKcee4RHALnl13ATdUennHwdy7RWEDUFqiAfrYtfqXvSyaF0rH-YrIQpyBrR2EdErK2g6FiihmzWLMCijYEvOmLjpYQdq6SP7g

But the page says "Invalid callback url" and does not return back to the Fitbit iOS app from Mobile Safari. I'm stuck.

 

I tried the example with authorizing the Fitbit Web API and it worked. The redirects happen so quickly that I can't compare the redirect from the Spotify Web API to the redirect of the Fitbit Web API.

 

Best Answer
0 Votes
6 REPLIES 6

I had a typo in one of my Spotify scopes in my JSX that was not in the authorization page URL I constructed to test on my laptop. I was also able to observe that Fitbit adds a state parameter to the authorization page that likely is needed to complete the authorization through Fitbit's side. Here's the updated JSX:

<Page>
    <Oauth
        settingsKey="oauth"
        title="Spotify Login"
        label="Spotify"
        status="Login"
        authorizeUrl="https://accounts.spotify.com/authorize"
        requestTokenUrl="https://accounts.spotify.com/api/token"
        clientId="redacted"
        clientSecret="redacted"
        scope="user-modify-playback-state user-read-playback-state user-library-read user-library-modify"
        onReturn={async (data) => {
            console.log(`Settings: Auth return`);
            console.log(data);
        }}
        onAccessToken={async (data) => {
            console.log(`Settings: Auth succeeded`);
            console.log(data);
        }}
    />
</Page>

So now I'm able to get from OAuth consent to redirect and back to Fitbit, but the `onAccessToken` is never called. I saw in another forum topic that I could add a `onReturn` listener. I have added it and see that `code` and `state` are being returned. What is the best way to debug this?

{
    code = "AQDQlgxsWfGVv9e6d6n01rpFlhDfqf8zWCjDW_olh5tf665Jlibg_tGcNmYA03h64_-CVNwEFAOHjePKhUzIQRFgpKlGDssiUHNSYWYlXL8_oAAx6jvHxFttiNe1pp43vXWBjId7Uto1-_dqWJNt9EUUOF_1Q2W3R28jLMeStbAnt7pSkyXctGiLzhaAyp_zJuXoetJJRH-iM75JI7ZMBqOp6rsNFkmhoEfA2dTpc1pXipRAB7opOs7c4br3PLdvaKuhTb8ftr5VzTKL03VTUdQmxdZ7mrzW0XnzwE87DlRiSp3LsIMog4seCu961f3CPtzhxQfCVutw594huPlfxNAvrgOQDm4FafLZBjEXG59bYvvyfTVHSw";
    state = "%7B%22nonce%22%3A%226jOQR6IZjMKtIJqTmycf6I0AzNcjWmwb0x0cHVHEhUzSwpdZ39A9IMhmjgSxsfg5V_pUkW8oYd9nll0gaOdT9slwsOj8noQI56P26K0jQVBHPAozPoOoJImcWP-xtGlxU6nFCRyHl_uMMJZwyXBW6yVfHmnDbPE4W8pvTIvo_ug%22%7D";
}

But again, onAccessToken is not being called, so something is failing silently.

Best Answer
0 Votes

As an experiment, I took the `code` and `state` returned in the console log from the `onReturn` and manually did the request for the access token and my request succeeded. I suspect something on the Fitbit side seems to not be performing the final step of the OAuth process.

 

My successful cURL:

 

 

curl -X "POST" "https://accounts.spotify.com/api/token" \
     -H 'Content-Type: application/x-www-form-urlencoded; charset=utf-8' \
     -u 'clientidredacted:clientsecretredacted' \
     --data-urlencode "code=AQDImOC43nZlkR7krCK3byLX52_GBIqWEsUzTyW40zbmgyEDh1fr1yLGw-Z_0Rj_D1353QOmoY1E8ass_8GOEVLqkWffJU5iCuEoxD_aWNhzANh56nIMZO5BV0P-ABFP3PLoi_2yUmdm0RFLBOUIDwAxXb0l5GqBSKWVvwSzFdzXaT_HDsy_smjOtx3hSD2u0IVWU8Gb6-C5HjNQfCavcWuBTvj60YkUTU8AKXxKZJ_0aNrowtLR2Fksk3x5Ljkxrmoas4yRTicL0zzyXetASQt9j5AnPFvzQJROIlCy4OBwer4bXIMt8X_p-UwEt0ei34SMCX-1cZyJFHsJgrtg0RPi5Y-55oDIRbjy1hVXHkZX4mIqBZv7lw" \
     --data-urlencode "redirect_uri=https://app-settings.fitbitdevelopercontent.com/simple-redirect.html" \
     --data-urlencode "state=%7B%22nonce%22%3A%22NPOljSzJh4JmgwoT5b6MGcBhqe9kC3ZmdItic0bvgFbTwe8G2VLi4shKSTawNEs2lixQIplf7PdIRIklWNvtLa79dXbtbIdkQRbxeBEz3Zp31nxscmWTfCVMTlv1npiq8KDuW6E-6dkPeE6q7MWzpKYVP0lTXW_qYw4rkvgErB8%22%7D" \
     --data-urlencode "grant_type=authorization_code"

 

Best Answer
0 Votes

I spent quite a lot of time on this today, but also can't get it working. One of our engineers will take a look.

Best Answer

I suspect the issue on Fitbit's side might be related to this build-time error on the settings JSX:

 

TS2468: Cannot find global value 'Promise'.
Best Answer
0 Votes

I am still unable to get around the build error:

TS2468: Cannot find global value 'Promise'.

I have downloaded promise code, imported into app file that exports global variable

But, still my settings jsx file complains when I have a callback with async on it:

 

jsx file:

 onReturn={async (data) => {
console.log(JSON.stringify(data));
}}

 

index file:

import Promise from './promise';

 

 

Best Answer
0 Votes

When we select the OAuth 2.0 Application Type * as a Client  and Callback URL * https://localhost/compete4hope/FitbitApi/GetProfile then get profile data but not getting the friends data. 

When we select the OAuth 2.0 Application Type * as a Server  and Callback URL https://oauth.io/auth then get friends data but not getting  current user login data.

So please provide single way to getting both data 

Best Answer
0 Votes