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

invalid_grant: Authorization code invalid - directly after regranting access

ANSWERED

Hey everbody out there 👋

We have developed native apps for Android and iOS that implement the Fitbit SDK to read the users activity/training and body weight data. This was 2 years ago and so far everything was working perfectly.

Since a few weeks we are having trouble in our Android app with the OAuth flow. Here is an example flow:

  1. Inside the app the user clicks on a "Connect Fitbit" button
  2. A WebView opens up for the OAuth and permission flow (https://www.fitbit.com/oauth2/authorize)
  3. The user sets the required permission and accepts
  4. The user is redirected to the app where the OAuth flow begins
  5. Access is granted. Fitbit data is imported into our app and shown there

This is the normal and expected case. So far we were able to repeat this as often as we wanted (or the user wanted). When connected to Fitbit our app shows a "Disconnect Fitbit" button the undo the binding and remove all Fitbit related data from our app. When disconnecting and repeating the connection flow like described above we get an error from the Fitbit API with the following reason:

 

{
   "errors":[
      {
         "errorType":"invalid_grant",
         "message":"Authorization code invalid: dedcacdd0db45cbfab8a00d124059de84d4ed2eb Visit https://dev.fitbit.com/docs/oauth2 for more information on the Fitbit Web API authorization process."
      }
   ],
   "success":false
}

 

 

Okay! So we've got a problem here. The docs are - unfortunately - not very helpful ad led to no solution. So we played around and tried different ways and to kind-of-debug the problem. And after some (not very scientific) research we've found a solution to the problem:

  1. Do step 1 & 2 like described above. We will be automatically logged into our account as we have already visited the website before
  2. Logout and login again
  3. Go on from step 3 like described above

Now we are having success *yay*!!! So this seems to be a workaround for our users. And it also seems like we are not doing anything wrong there. We have not changed this flow during the last 12 month and it just stopped working a few month ago.

 

Let's have a look into the blackbox and behind the scenes:

  1. When connecting with Fitbit we will firstly generate a randomVerifier and a derivedVerifier. For example:

 

randomVerifier: xbdWGHY_sUUka111yAvVu3ObIMrZ8pXOOb5hNoTL1o2Ec4r1LHRqC0RAiS_0GhNh2p9XfvAtryyD-Z-pLG0nog
derivedVerifier: 6Z-sktf2D01IWu_2VTIvSe1RQCVV2CV_Wtu7qGzB4SM​

 

  • Now we will open up a WebView (Chrome Custom tabs) with the following URL:

 

https://www.fitbit.com/oauth2/authorize?
	client_id=<secret_id>&
	response_type=code&
	scope=weight activity&
	prompt=consent&
	code_challenge=6Z-sktf2D01IWu_2VTIvSe1RQCVV2CV_Wtu7qGzB4SM&
	code_challenge_method=S256&
	redirect_uri=<host>://oauth/fitbit

 

  • Now the flow described above is done by the user. After that the website will redirect to the given uri directly into our app. For example:

 

<host>://oauth/fitbit?code=dedcacdd0db45cbfab8a00d124059de84d4ed2eb#_=_​

 

  • Now we will parse out the code to request an access token from the Fitbit API. Therefore we are building the following url:

 

https://api.fitbit.com/oauth2/token?
	client_id=<secret_id>&
	grant_type=authorization_code&
	code=dedcacdd0db45cbfab8a00d124059de84d4ed2eb&
	redirect_uri=<host>://oauth/fitbit​

 

  • Now we will get a response with a http code 400 and the error message mentioned at the beginning of this post. It says we are using an 

 

invalid_grant​

 

 

We are not having any idea what might be wrong here. It works on the first connect and always after logging out and in again. It also works again after waiting an undefined amount of time. Sometimes it just works again after 24 hours and sometimes it takes up to 3 days. Also this error is only facing the Android platform. iOS is still working like always before...

 

Is anyone out there facing the same issue? Does anyone knows a solution or has a hint on what we have to do?

Best Answer
0 Votes
1 BEST ANSWER

Accepted Solutions

Hi @FDDB 

 

Thank you for providing me with your client ID.   Looking in our logs for your /oauth2/token requests which are failing with a 400 Invalid Grant error, I see a syntax problem when grant_type=authorization_code.

 

The parameters and values you're using are

client_id=<client_secret>

grant_type=authorization_code

code=<code_verifier or authorization_code>

redirect_uri=<redirect_uri>

 

The correct syntax is

code=<authorization_code provided after a user consents>

grant_type=authorization_code

client_id=<6 character client ID that you provided me>

redirect_uri=<redirect_uri>

code_verifier=<code_verifier>

 

You should never post your client secret in the HTTP request unless you've properly built the Basic token.

 

Please check your syntax and see if you can make these changes.  

Gordon Crenshaw
Senior Technical Solutions Consultant
Fitbit Partner Engineering & Web API Support | Google

View best answer in original post

Best Answer
0 Votes
8 REPLIES 8

Hi @FDDB 

 

Thank you for all the detail.  I'm glad you found a workaround.   However, it shouldn't be necessary.   I would expect you to receive a brand new authorization code when the user tries to consent the second time.   Would you confirm that you are receiving a new authorization code?

 

If the problem is only happening on Android, then I would suspect the behavior is related to Chrome.  Can you confirm roughly when this started to occur?   Also, it looks like you are using authorization grant flow with PKCE, correct?

 

Gordon

Gordon Crenshaw
Senior Technical Solutions Consultant
Fitbit Partner Engineering & Web API Support | Google
Best Answer
0 Votes

Hi Gordon, thank you very much for your reply!

 

YES, we are receiving a new authorization code (but then getting a new access token with it fails).

YES, we are using authorization grant flow with PKCE.

 

We also thought about having a chrome problem here so we tried different versions of androidx.browser:

  • 1.0.0 (the version we were using from 2018 until July 2020)
  • 1.2.0 (we upgraded to in July this year)
  • 1.3.0-alpha05 (a few weeks ago for testing)

Unfortunately the problem occurs in all of these versions. We roughly estimate the first occurrance was  4-5 weeks ago. 

Best Answer
0 Votes

Hey Gordon,

 

do you have any ideas on what me might be doing wrong? 

Best Answer
0 Votes

Hi @FDDB 

 

Would you please private message me your client ID?   I'll like to see what your application is doing.

 

Thanks!

Gordon

Gordon Crenshaw
Senior Technical Solutions Consultant
Fitbit Partner Engineering & Web API Support | Google
Best Answer
0 Votes

Hi @FDDB 

 

Thank you for providing me with your client ID.   Looking in our logs for your /oauth2/token requests which are failing with a 400 Invalid Grant error, I see a syntax problem when grant_type=authorization_code.

 

The parameters and values you're using are

client_id=<client_secret>

grant_type=authorization_code

code=<code_verifier or authorization_code>

redirect_uri=<redirect_uri>

 

The correct syntax is

code=<authorization_code provided after a user consents>

grant_type=authorization_code

client_id=<6 character client ID that you provided me>

redirect_uri=<redirect_uri>

code_verifier=<code_verifier>

 

You should never post your client secret in the HTTP request unless you've properly built the Basic token.

 

Please check your syntax and see if you can make these changes.  

Gordon Crenshaw
Senior Technical Solutions Consultant
Fitbit Partner Engineering & Web API Support | Google
Best Answer
0 Votes

Yep, that's it. It's working now. Thank you very much!!!! 

But I'm still wondering why this code was running without any problems since 2018...nvm

Best Answer
0 Votes

Hello. I have implemented as you answered here. But I still get error.

When I use postman, it is working. But when I use alamofire, I am getting error.

Please help me.

Best Answer
0 Votes

Hi @ksmks0921 

 

What syntax and error message are you getting with alamofire?   

Gordon Crenshaw
Senior Technical Solutions Consultant
Fitbit Partner Engineering & Web API Support | Google
Best Answer
0 Votes