[google-api] invalid_grant trying to get oAuth token from google

Using a Android clientId (no client_secret) I was getting the following error response:

{
 "error": "invalid_grant",
 "error_description": "Missing code verifier."
}

I cannot find any documentation for the field 'code_verifier' but I discovered if you set it to equal values in both the authorization and token requests it will remove this error. I'm not sure what the intended value should be or if it should be secure. It has some minimum length (16? characters) but I found setting to null also works.

I am using AppAuth for the authorization request in my Android client which has a setCodeVerifier() function.

AuthorizationRequest authRequest = new AuthorizationRequest.Builder(
                                    serviceConfiguration,
                                    provider.getClientId(),
                                    ResponseTypeValues.CODE,
                                    provider.getRedirectUri()
                            )
                            .setScope(provider.getScope())
                            .setCodeVerifier(null)
                            .build();

Here is an example token request in node:

request.post(
  'https://www.googleapis.com/oauth2/v4/token',
  { form: {
    'code': '4/xxxxxxxxxxxxxxxxxxxx',
    'code_verifier': null,
    'client_id': 'xxxxxxxxxxxxxxxxxxxxxx.apps.googleusercontent.com',
    'client_secret': null,
    'redirect_uri': 'com.domain.app:/oauth2redirect',
    'grant_type': 'authorization_code'
  } },
  function (error, response, body) {
    if (!error && response.statusCode == 200) {
      console.log('Success!');
    } else {
      console.log(response.statusCode + ' ' + error);
    }

    console.log(body);
  }
);

I tested and this works with both https://www.googleapis.com/oauth2/v4/token and https://accounts.google.com/o/oauth2/token.

If you are using GoogleAuthorizationCodeTokenRequest instead:

final GoogleAuthorizationCodeTokenRequest req = new GoogleAuthorizationCodeTokenRequest(
                    TRANSPORT,
                    JSON_FACTORY,
                    getClientId(),
                    getClientSecret(),
                    code,
                    redirectUrl
);
req.set("code_verifier", null);          
GoogleTokenResponse response = req.execute();