Help

OAuth2 : Problem with /token request

Topic Labels: API
3125 3
cancel
Showing results for 
Search instead for 
Did you mean: 
clicdata
4 - Data Explorer
4 - Data Explorer

 

Hello,

I created Oauth2 integrations on your website, and now I do the authentication request and then the token creation request, like described on your doc.

The problem is that I can get the access token, but it doesn't work every time, it seems that I get to randomly. However I always do the same way. I also tried with Insomnia and Postman, and when it does not work, I get the response :

'Response': '{"error":"invalid_grant","error_description":"Unrecognized grant code"}'

I verified, the code_verifier is the same in the two request (/authorize and /token), so the code_challenge is the same as in the response.

Here is my request to /authorize : $"https://airtable.com/oauth2/v1/authorize?response_type=code&client_id={OAuth2Infos.ClientId}&code_ch...}"

And for the /token request, I send :

authorization_code:<received_authorization_code>, redirect_uri={OAuth2Infos.RedirectUrl}, grant_type="authorization_code", code_verifier=<our_code_verifier>,

and in the header request I add my clientID and my clientSecret as basic authentication, the request is sent as x-www-form-urlencoded.

I cannot determine why it works or not, but I precise that the /authorize request works fine.

Here is a response retrieved from Insomnia :

OAuth 2.0 Error invalid_request Must include both "code_challenge" and undefined

3 Replies 3
Will_Powelson
Airtable Employee
Airtable Employee

Hi @clicdata,
I'm an engineer on Airtable's API team. The response you're receiving can arise from several conditions and is intentionally obfuscated as a security measure. Three possible issues come to mind

  1. Your /token request occurs ~10 minutes after the response
  2. You are sending multiple requests for the same grant code (grant codes are one time only)
  3. The redirect URI you sent in the authorization request does not exactly match the redirect URI
  4. You are sending the incorrect code_verifier, this may mean that you are not generating your code-verifier in the way Airtable accepts

In terms of next steps I recommend you try making a request with our example repo and comparing the requests it makes to that ones you've created.

If you continue to have issues, you can DM me your clientId and I may be able to assist you further.

clicdata
4 - Data Explorer
4 - Data Explorer

Thank you for you're answer, 

Actually I request /token just after the /authozire request, and my grant code is new each time, here is a code snippet :

Public Function GetAuthorization() As OAuthAuthorization Implements IOAuthConnector.GetAuthorization
' Challenge code
Dim rng = RandomNumberGenerator.Create()
Dim bytes = New Byte(50) {}
rng.GetBytes(bytes)

Me.PKCECodeVerifier = Convert.ToBase64String(bytes).TrimEnd("=").Replace("+", "-").Replace("/", "-")

Dim codeChallenge As String
Using sha = SHA256.Create()
Dim challengeBytes = sha.ComputeHash(System.Text.Encoding.UTF8.GetBytes(PKCECodeVerifier))
codeChallenge = Convert.ToBase64String(challengeBytes).TrimEnd("=").Replace("+", "-").Replace("/", "-")
End Using

Return New OAuthAuthorization With {
.Url = $"{OAuth2Infos.AuthorizeUrl}?response_type=code&client_id={OAuth2Infos.ClientId}&code_challenge={codeChallenge}&code_challenge_method=S256&scope={OAuth2Infos.Scope}&redirect_uri={OAuth2Infos.RedirectUrl}"

End Function

My redirectURI is always the same, for both requests.

If one of these point was not good, I think it wouldn't work at all.

I DM you my ClientID.

Thank you

Will_Powelson
Airtable Employee
Airtable Employee

Hi @clicdata,

Based on the clientId you sent me, I can confirm that the code_verifier you are sending in your requests does not match the code_challenge in the initial request. This implies that there is a bug when generating your code_challenge, or that you are somehow sending incorrect pairs of code_verifier and code_challenge after generating them.

For an example of how to correctly generate these values, please see our example repo.