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);
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.
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
Related
I am attempting to send a plain POST request via Postman. I did the same via Curl and my server sees it just fine. Here is the settings for the Body:
And here is the request in the console:
My express server is not seeing the body variables. With curl like this it does:
curl -X POST https://xxx.appspot.com -d "volume=123&content=foobar"
What do I need to change for this to work?
The two examples are not equivalent, because with Postman you have Content-Type: text/plain header set, but sending data via curl -d option, sets Content-Type: application/x-www-form-urlencoded. From curl manual page:
-d, --data <data>
(HTTP MQTT) 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.
I don't have any experience with Postman, but my guess would be you need to select x-www-form-urlencoded button instead of current raw button.
I'm trying to get information about a bot using the bot token, like the way to get user, passing on the header Authorization: Bearer ${userToken}. I'm sending a request to the route GET https://discord.com/api/oauth2/applications/#me passing on the header Authorization: Bearer ${botToken}, and the response is 401. But if I send a request to the route GET https://discord.com/api/oauth2/users/#me with my token in the header, I got my data. I don't have sure if the bot token can be used for this, I check on the docs, and I found this https://discord.com/developers/docs/topics/oauth2#get-current-application-information, but I don't understand what I need to pass in the header to get the data.
Yes, and you're very close to the correct solution.
The issue is with the "Authorization" header, instead of "Bearer" you should use "Bot" when using a token for a bot user.
In your case the header should be:
Authorization: Bot ${botToken}
CURL example:
curl --location --request GET 'https://discord.com/api/oauth2/applications/#me' \
--header 'Authorization: Bot <BOT TOKEN HERE>'
Regarding the question about "https://discord.com/api/oauth2/users/#me", try using "https://discord.com/api/users/#me" instead.
I have to access a private API (one of Air France flight company's API), and in order to use any of their API, I need an access token.
So in their guide, they say we need to use this cURL to get the token :
$ curl https://www.klm.com/oauthcust/oauth/token -d 'grant_type=client_credentials' -u fakeKey:fakeSecret
TERMINAL
When I execute this cURL in my terminal, and replace the fakeKey and fakeSecret (which I can't give you here unfortunately) by my own, it's working well and I got this answer (with a proper token in place of :
{
"access_token": <TOKEN>,
"token_type":"bearer",
"expires_in":3600
}
POSTMAN
When I do it in Postman, here is what I fill :
URL:
POST: https://www.klm.com/oauthcust/oauth/token
Authorization:
type: Basic Auth
Username: my secret Username
Password: my secret password
Headers:
Authorization: automatically generated from my username and password
Content-Type: application/x-www-form-urlencoded
Body
checked x-www-form-urlencoded
grant_type: client_credentials
That's all, and when I click on SEND, I got my answer and my token.
FETCH / AXIOS / HTTPRequest
So as I am not so good yet in fetching data, I used https://kigiri.github.io/fetch/ to translate from my cURL to a fetch JS method. It return me this code :
fetch("https://www.klm.com/oauthcust/oauth/token", {
body: "grant_type=client_credentials",
headers: {
Authorization: "Basic <HASH_COMPILED_FROM_USERNAME_PASSWORD>",
"Content-Type": "application/x-www-form-urlencoded"
},
method: "POST"
})
The <HASH_COMPILED_FROM_USERNAME_PASSWORD> is exactly the same as the one Postman compiled.
So this fetch seems OK for me, however on Chrome it returns a Response for preflight has invalid HTTP status code 503.
Opera is returning me Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin <MY_WEBSITE> is therefore not allowed access. The response had HTTP status code 503.
However it seems weird that the mistake come from their site, I think it's more something that I missed in my fetch request. Do you have an idea ?
Thanks !
Well, the answer finally has been : the request must come from a back-end, otherwise the response won't have anything inside it (or error 503). Thanks #sideshowbarker to your well explaining comments !
I am getting 400 error message as shown in image below, when I try out the Translation API using Try it out link http://docs.microsofttranslator.com/text-translate.html
I am using the Access Key generated from Azure Portal for Cognitive Services Free trial.
MS Azure Portal Link
I have read on MS support blogs and I tried all the suggestions mentioned in them. But everytime, I get the 400 Status error as shown below.
Can someone please help me to resolve this issue??
You need to get an access token first (docs here) by doing a POST request:
curl --header 'Ocp-Apim-Subscription-Key: <YOUR-API-KEY>' --data "" 'https://api.cognitive.microsoft.com/sts/v1.0/issueToken'
And then use that token in the Authorization header. (appId has been deprecated).
curl -X GET --header 'Accept: application/xml' --header 'Authorization: Bearer <YOUR-TOKEN>' 'https://api.microsofttranslator.com/v2/http.svc/Translate?&text=this%20is%20my%20name&from=en&to=af'
You can use Microsoft Translator API in 2 ways (see the docs):
in 1 step: invoke (GET) https://api.microsofttranslator.com/V2/Http.svc/Translate?text=Neoliberismo&from=it&to=en, passing Ocp-Apim-Subscription-Key: your_subscription_key as request header
in 2 steps, with OAuth:
invoke (POST) https://api.cognitive.microsoft.com/sts/v1.0/issueToken, passing Subscription-Key=your_subscription_key as query parameter or better passing Ocp-Apim-Subscription-Key: your_subscription_key as request header
you'll get a token that expires after 10 minutes
invoke (GET) https://api.microsofttranslator.com/V2/Http.svc/Translate?text=Neoliberismo&from=it&to=en, passing Authorization: Bearer the_token as request header
I've been trying to plug into the Toggl API for a project, and their examples are all using CURL. I'm trying to use the C# wrapper which causes a bad request when trying to create a report, so I thought I'd use Postman to try a simple HTTP request.
I can't seem to get the HTTP request to accept my API Token though. Here's the example that they give (CURL):
curl -u my-secret-toggl-api-token:api_token -X GET "https://www.toggl.com/reports/api/v2/project/?page=1&user_agent=devteam#example.com&workspace_id=1&project_id=2"
I've tried the following HTTP request with Postman with a header called
api_token with my token as the value:
https://www.toggl.com/reports/api/v2/project/?user_agent=MYEMAIL#EMAIL.COM&project_id=9001&workspace_id=9001
(changed ids and email of course).
Any help on how to use the CURL -u in HTTP would be appreciated, thanks.
The easy way is adding credential into url as user:pass# format.
https://my-secret-toggl-api-token:api_token#www.toggl.com/reports/api/v2/project/?page=...
<---------------------------------->
Alternately you can use credential with your http header like below:
Authorization: Basic XXXXXX
Here XXXXXX is base64(my-secret-toggl-api-token:api_token)
As explained to me in another post, you can pass the api token to the user property if you are using HttpWebRequest:
request.Headers.Add("Authorization", "Basic " + Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes($"my-secret-toggl-api-token:api_token")));
Using fetch
In node environment, your request might look something like so:
const url = 'https://www.toggl.com/reports/api/v2/project/page=1&user_agent=devteam#example.com&workspace_id=1&project_id=2';
const token = 'my-secret-toggl-api-token:api_token';
fetch(url, {
method: 'GET', // not required
headers: {
Authorization: `Basic ${Buffer.from(String(token)).toString('base64')}`,
},
})