Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bad Request when using Google OAuth2.0

I am receiving a 400 bad request when using Google OAuth from within Salesforce. The following error is in regards to invalid grant_type, but if you look at the documentation under 'Using Refresh Token' you will see that it is correct.

https://developers.google.com/identity/protocols/OAuth2WebServer

Error:

{
 "error": "unsupported_grant_type",
 "error_description": "Invalid grant_type: "
}

I am attempting to exchange a refresh_token for an access token and can successfully do it using CURL, with the following code.

curl \
  -d refresh_token=REFRESH_TOKEN \
  -d client_id=CLIENT_ID \
  -d client_secret=CLIENT_SECRET \
  -d grant_type=refresh_token https://www.googleapis.com/oauth2/v4/token

The code that I am using inside Salesforce:

    Http http = new Http();
    HttpRequest req = new HttpRequest();

    req.setHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
    req.setHeader('Content-Length', '0');
    req.setHeader('client_id', 'CLIENT_ID');
    req.setHeader('client_secret', 'CLIENT_SECRET');
    req.setHeader('refresh_token', 'REFRESH_TOKEN');
    req.setHeader('grant_type', 'refresh_token'); 

    req.setEndpoint('https://www.googleapis.com/oauth2/v4/token');
    req.setMethod('POST');

    return http.send(req);
like image 359
Coova Avatar asked Dec 23 '22 23:12

Coova


2 Answers

The -d curl option sends the data in the request body using the application/x-www-form-urlencoded content type which is one of the supported ways of sending those parameters in OAuth2.

-d Sends the specified data in a POST request to the HTTP server, in the same way that a browser does when a user has filled in an HTML form and presses the submit button. This will cause curl to pass the data to the server using the content-type application/x-www-form-urlencoded.

In the Salesforce code you're setting the correct content type, but then are sending the OAuth2 related parameters as additional headers instead of sending them in the request body.

You need to update the code to send the parameters in the request body using the application/x-www-form-urlencoded encoding.

like image 177
João Angelo Avatar answered Dec 27 '22 06:12

João Angelo


I caught the same issue in fiddler. I added this comment because it may be helpful to somebody.

https://oauth2.googleapis.com/token
Content-Type: application/x-www-form-urlencoded

Request Body:
code=<some code here>&
client_id=your_client_id&
client_secret=your_client_secret&
redirect_uri=https%3A//oauth2.example.com/code&
grant_type=authorization_code

Goole api response:

{"error": "unsupported_grant_type",  "error_description": "Invalid grant_type: "}

The issue occurred because the request body has line breaks between each parameter. if you delete all the line breaks, leaving all values in a single row request will be work fine. e.g. request body:

code=<some code here>&client_id=your_client_id&client_secret=your_client_secret&redirect_uri=https%3A//oauth2.example.com/code&grant_type=authorization_code
like image 42
Andrey Ravkov Avatar answered Dec 27 '22 05:12

Andrey Ravkov