Bad Request when using Google OAuth2.0
Asked Answered
W

2

6

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);
Wheel answered 29/11, 2016 at 21:46 Comment(0)
W
10

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.

Walton answered 30/11, 2016 at 9:44 Comment(2)
req.setHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8'); I modified the above line by removing the 'charset=UTF-8', but I still receive the same error listed above.Wheel
What you need to change is the way you pass the OAuth parameters like client_id, grant_type, etc. They can't use the setHeader and instead be passed in the POST request body.Blesbok
F
7

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
Fated answered 12/9, 2020 at 7:4 Comment(1)
You saved me hours of experiments!Orbicular

© 2022 - 2024 — McMap. All rights reserved.