I am trying to send Https post request using NodeJS, but getting back 'Bad request'. At the same time when I send the same request via curl everything is fine. Can you help to fix the Node code:
var options = {
host: 'api.wit.ai',
port: 443,
path: '/converse?v=20170611&session_id=125abc&q=Hi',
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
'Authorization': 'Bearer <token>'
}
};
var req = https.request(options, function(res) {...}
The curl query:
curl -XPOST 'https://api.wit.ai/converse?v=20170611&session_id=125abc&q=Hi' \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-H 'Authorization: Bearer <token>'
With http.request() your post data is not to be sent in the query string. If you include a query string, it is sent as a query string. Your post data needs to be sent with req.write(data). See the code example in the doc.
Probably your server is returning that error because there is no data in the body of the POST.
Related
i'm facing a problem with my Node.js backend.
I have to call an API that sadly requires the Authorization header duplicated, one with a Basic token and one with a Bearer token.
Unfortunately a third party provides the api, therefore i have no control over it.
Also that API for some reason doesn't work if i concatenate the two values with a comma (Basic foo,Bearer bar), so sadly that is not a solution.
I'm able to do the request with curl in the terminal
curl --location --request POST 'https://service.com/test' --header 'Authorization: Basic token' --header 'Authorization: Bearer token' --header 'Content-Type: application/json' --data-raw '{"foo": "bar"}'
I have tried many different http request libraries but all of them, rightfully, use a dictionary to store headers, which does not accept a duplicated key.
Do you know any library that treats the headers differently, or any other workaround to solve this issue?
Thanks a lot
Fire up netcat to see what a server would see:
nc -l -p 10000
Client code:
const axios = require('axios');
async function main() {
axios({
url: 'http://localhost:10000/',
method: 'POST',
headers: {
'Authorization': [
'Authorization: Basic token',
'Authorization: Bearer token',
],
'Content-Type': 'application/json',
},
data: {
'foo': 'bar',
},
});
}
main().then(console.log).catch(console.log);
Netcat prints:
POST / HTTP/1.1
Accept: application/json, text/plain, */*
Content-Type: application/json
Authorization: Authorization: Basic token
Authorization: Authorization: Bearer token
User-Agent: axios/1.2.0
Content-Length: 13
Accept-Encoding: gzip, deflate, br
Host: localhost:10000
Connection: keep-alive
{"foo":"bar"}
How to post Json data via node js either with form-data or via request ?
Using form-data. It does not allow to send custom headers and if replaced bodyParams.getHeaders() with custom headers it does not send request data
https://www.npmjs.com/package/form-data
const smsResponse = await request.post(url, bodyParams, {headers:bodyParams.getHeaders()})
Using Request it does not allow to send parameters
require('request');
const subscription = await request.post(url, body, {headers:{'Accept':'text/html'}})
Postman curl request It works via postman. tried to use postman nodejs request code but it fails
curl --location --request POST 'https://personalsite.com//test.php' \
--header 'accept: text/html' \
--header 'SECRET-TOKEN-MESSAGE: dataforport' \
--header 'Content-Type: application/json' \
--header 'Cookie: PHPSESSID=1d2shuebo7lal8sn2itgppvfk4' \
--data-raw '{
"mobileno": "888888888",
"messagetext": "Test message"
}'
Tried but it did not worked
Node.js: How to send headers with form data using request module?
Use new Headers() to build your header.
https://developer.mozilla.org/en-US/docs/Web/API/Request/Request
var myHeaders = new Headers();
myHeaders.append('Accept', 'text/html');
var myInit = { method: 'POST',
headers: myHeaders,
mode: 'cors',
cache: 'default',
body: JSON.stringify({coffee: 'yes...'})
};
var myRequest = new Request('https://personalsite.com//test.php',myInit);
fetch(myRequest).then(function(response) {
console.log(response)
});
I'm currently trying to implement Polar accesslink API on an app, but when trying to POST a new user I still get this error:
url: 'https://www.polaraccesslink.com/v3/users/',
status: 400,
statusText: 'Bad Request',
headers: Headers { [Symbol(map)]: [Object: null prototype] },
counter: 0
I already have the authorization token, which I know expires every 10min, and I'm using the service through a function that takes the token and the userID as parameters. This is my code:
postUser(memberId: string, token: string) {
const inputBody = { 'member-id': memberId };
const headers = {
'Content-Type': 'application/xml', 'Accept': 'application/json', 'Authorization': 'Bearer ' + token
};
const options = {
method: "POST",
headers: headers,
body: JSON.stringify(inputBody)
}
return new Promise<object>((resolve, reject) => {
fetch('https://www.polaraccesslink.com/v3/users', options)
.then(function(res: any) {
console.log(res)
return res.json();
}).then(function(body: any) {
console.log(body);
});
})
}
I'm implementing it the same way as it is specified in https://www.polar.com/accesslink-api/?javascript--nodejs#users but really don't know what might I be doing wrong. Thanks for helping me!.
I don't have experience with this specific API but i can see you send in the header Content-Type the value application/xml but the request body is JSON formatted.
Try send application/json in that header.
The Content-Type header is used in HTTP to specify the body mime type.
more info in: Content-Type HTTP Header - MDN
I also see this is the exact code in the sample but notice they have 2 sample requests and 2 sample results, one in XML and one in JSON each.
Any ideea why this POST gives 'invalid_Request'?
curl --location --request POST 'https://polarremote.com/v2/oauth2/token?grant_type=authorization_code&code=1f9edc0c5e60a0bab4fd3f1f00571a58' --header 'Authorization: Basic ... DA4OS05ZDc2LTJlNTQwZjFkZTc5ZA==' --header 'Content-Type: application/x-www-form-urlencoded' --header 'Accept: application/json'
I have tried every way I can think of to format this cURL request into something I can do server side on node and I keep getting back an invalid credentials response. I know the creds are valid so I must come to the conclusion that the code is making the wrong type of request.
cURL request:
curl --request GET \
--url https://api.timekit.io/v2/bookings\
--header 'Content-Type: application/json' \
--user : api_key_dfagafrgaegrfareVhROys9V1bUJ1z7
my format:
var options = {
url: 'https://api.timekit.io/v2/bookings',
headers:{
"Content-Type": "application/json",
'user': APP_KEY
},
method:'GET'
};
function callback(error, response, body) {
if (!error && response.statusCode == 200) {
console.log(body);
}
}
request(options, callback);
I think you mean --user user:password in your curl command.
When you pass --user to curl, it sends it to the server as an basic authorization header (with the user:password encoded using base64). You can try this by running it against httpbin.org:
curl --request GET --url http://httpbin.org/headers --header 'Content-Type: application/json' --user foo:bar
{
"headers": {
"Accept": "*/*",
"Authorization": "Basic Zm9vOmJhcg==",
"Connection": "close",
"Content-Type": "application/json",
"Host": "httpbin.org",
"User-Agent": "curl/7.61.1"
}
}
As you can see, they received the header "Authorization": "Basic Zm9vOmJhcg==" where Zm9vOmJhcg== is the base64 encode of foo:bar
I am using nodejs to get bearer token i my code looks like
var fs = require("fs");
var https = require("https");
var querystring = require("querystring");
var bearer = "cunsomer_key:cunsomer_secret"
var base64ed = new Buffer(bearer).toString("base64");
var options = {
port: 443,
hostname: "api.twitter.com",
path: "/oauth2/token",
method: "post",
headers: {
Authorization: "Basic " + base64ed,
"Content-Type": "Content-Type: application/x-www-form-urlencoded;charset=UTF-8",
"User-Agent": "socialginie"
},
key: fs.readFileSync("./testssl.key"),
cert: fs.readFileSync("./testcert.cert"),
}
var req = https.request(options, res => {
res.on("data", d => {
console.log(d.toString());
})
})
req.on("error", e => {
console.log(e);
});
req.write(querystring.stringify({
"grant_type": 'client_credentials'
}))
req.end();
The expected return from the api is my bearer token and it does so in postman app but here i get the error {"errors":[{"code":170,"message":"Missing required parameter: grant_type","label":"forbidden_missing_parameter"}]}
Does anyone have any idea why api server cannot read the grant type
Your problem is just a typo. On this line:
"Content-Type": "Content-Type: application/x-www-form-urlencoded;charset=UTF-8",
you are specifying "Content-Type" as part of the header value.
When I use this curl command, sending your invalid Content-Type, I see the same error you do:
$ curl --data "grant_type=client_credentials" -H "Authorization: Basic <credentials-omitted>" -H "Content-Type:" -H "Content-Type: Content-Type: application/x-www-form-urlencoded;charset=UTF-8" https://api.twitter.com/oauth2/token
{"errors":[{"code":170,"message":"Missing required parameter: grant_type","label":"forbidden_missing_parameter"}]}
If I correct the header, I get a token:
$ curl --data "grant_type=client_credentials" -H "Authorization: Basic <credentials-omitted>" -H "Content-Type:" -H "Content-Type: application/x-www-form-urlencoded;charset=UTF-8" https://api.twitter.com/oauth2/token
{"token_type":"bearer","access_token":"<token-omitted>"}