Node js if status of http post request is 401 then execute another post request - node.js

I have the below https post request, which is very simple. The code works as expected when using an active token. when using an expired token it receives a 401 error. This is ok. I would like to run a diiferent post request if i receive a 401.
what code can I add to make it check for 401 status and run a different post request? I'm new to node js. Should I use a function? promise?
const https = require('https');
const postData = JSON.stringify({
"data": [
{
"Company": "Test Company",
"Last_Name": "test",
"First_Name": "test",
"Email": "test#gmail.com",
}
],
"trigger": [
"test"
]
});
const options = {
method: 'POST',
hostname: 'www.host.com',
path: '/crm/xxx',
headers: {
'Authorization': 'oauthtoken 1000.xxxxxxxxxxxxx',
'Content-Type': 'application/json',
'Content-Length': postData.length
}
};
const req = https.request(options, (res) => {
console.log('Status Code:', res.statusCode);
if (res.statusCode == '401'){
// run other post request here? somewhere else?
console.log('rec 401 status code');
}else{
console.log('did not rec 401');
}
}).on("error", (err) => {
console.log("Error: ", err.message);
});
req.write(postData);
req.end();

Related

Axios Proxy Configuration causing Bad Request

I am trying to send a request to the particle cloud from a NodeJS application.
I am using Axios to make the PUT request. The application sends the request through a proxy server which is configured as well.
// axios proxy - not working
axios.default.put("https://api.particle.io/v1/devices/<deviceId>/ping", {}, {
proxy: {host: <proxy_ip>, protocol:'http', port:<port_no>},
headers: {
authorization: "Bearer <access_token>"
}
}).then((response) => {
console.log("Success", response.data);
}).catch((error) => {
console.log("Failed", error);
});
Error Message: Request failed with status code 400
When I send this request I get a 400 Bad Request response from the particle cloud.
But when I send the same request using the request module of NodeJS, the request is successful.
var options = {
method: 'PUT',
url: 'https://api.particle.io/v1/devices/<device_id>/ping',
proxy: {hostname: <proxy_ip>, protocol:'http', port:<port_no>},
headers:
{
authorization: 'Bearer <access_token>'
},
form: false
};
request(options, function (error, response, body) {
if (error) throw new Error(error);
console.log(response);
});
Response: body: '{"online":false,"ok":true}'
The request also works when the application was deployed on the open network and axios was used without the proxy configuration.
// axios without proxy - working
axios.default.put("https://api.particle.io/v1/devices/<deviceId>/ping", {}, {
headers: {
authorization: "Bearer <access_token>"
}
}).then((response) => {
console.log("Success", response.data);
}).catch((error) => {
console.log("Failed", error);
});
Questions:
Why is the request from Axios failing with proxy configuration?
Is this an inherent issue with Axios?
Regards.
Axios itself has a bug which isnt fixed yet.
To overcome this issue, https-proxy-agent can be used instead of axios proxy.
const HttpsProxyAgent = require('https-proxy-agent')
axios.default.put("https://api.particle.io/v1/devices/<deviceId>/ping", {}, {
headers: {
authorization: "Bearer <access_token>"
},
proxy: false,
httpsAgent: new HttpsProxyAgent('http://proxy_domain:port')
}).then((response) => {
console.log("Success", response.data);
}).catch((error) => {
console.log("Failed", error);
});

difficulty in getting authorization from dialogflow api v1. Getting error "Request failed with status code 401"

im using axios to connect my bot to dialog-flow API v1.it is returning a 401 error saying unauthorized?
i have all ready set up the headers and the data types to application/json.
var axios =require('axios');
var URL ='https://api.dialogflow.com/v1/';
let config = {
headers: {
"Authorization": "Bearer " + '4c52dfb9db61xxxxxxxxxxxxx',
"Content-Type": "application/json"
}
}
var bodyParameters = {
"queryInput": { "text":
{ }
},
"query": "hi hello",
"languageCode": "en",
"sessionId": "12345",
"timezone": "xxxxx"
};
axios.get(URL,bodyParameters, config)
.then(function(res){
console.log(res.data);
}).catch(function(error){
console.log(error);
});
is there some error in authorization?
after searching i found that it was much easy to do API request using node-fetch
fetch(URL+"query?v=20150910", {
body: JSON.stringify({query: "new york city", lang: "en", sessionId: "12345"}),
headers: {
'content-type': 'application/json',
"Authorization": "Bearer " + accessToken,
},
method: 'POST',
})
.then(response => response.json())
.then(data => {
console.log(data.result.fulfillment.speech);
return data.result.fulfillment.speech;
})
.catch(error => console.error(error))

Using CSRF Token from GET and Uses that in POST | 403 Forbidden | AWS Lambda

I am creating node.js function through aws lambda which makes a GET request to Hybris Market Place and gets a CSRF Token. Then I am using that token to make another POST request to post some data to Hybris Market place but I am getting an error of 403 Forbidden. Same thing works in Postman which I believe due to POSTMAN keeps GET session alive and hence CSRF token is still valid. How May I achieve that in AWS Lambda function. Below is my code. I am using promise to make two requests.
const https = require('https');
exports.handler = async (event, context, callback) => {
const tokenOptions = {
"host": "*******.s4hana.ondemand.com",
"path": "/sap/opu/odata/sap/***********/",
"port": null,
"headers":{
"authorization": "Basic ************=",
"cache-control": "no-cache",
"x-csrf-token": "fetch"
},
"method": "GET"
};
var getToken = (tokenOptions) => {
return new Promise((resolve,reject)=>{
const req = https.request(tokenOptions, (res) => {
var xToken = res.headers["x-csrf-token"];
var sCookies = res.headers["set-cookie"];
var response = [xToken,sCookies]
res.on('data', () => {
console.log('Successfully processed HTTPS response');
resolve(response);
});
res.on('end', () => {
});
});
req.on('error', function(){
reject('Request to get token failed.');
});
req.end();
});
};
var postContent = (response) => {
return new Promise((resolve,reject)=>{
var options = {
"method": "POST",
"host": "*********-***.s4hana.ondemand.com",
"path": "/sap/opu/odata/sap/*********/*******",
"port":null,
"headers":
{ "authorization": "Basic *******==",
"x-csrf-token": response[0],
"accept": "application/json",
"content-type": "application/json",
"cache-control": "no-cache",
},
"cookie":response[1],
"body":
{
/* Data I want to POST */
},
"json": true
};
const req = https.request(options, (res,data) => {
console.log(res.statusCode);
res.on('data', () => {
resolve('Successfully submitted.');
});
res.on('end', () => {
});
});
req.on('error', function(err,res){
reject('Request to get Post failed.');
});
req.end();
});
};
getToken(tokenOptions).then((response) =>{
console.log('Result: ' +response[0]);
return postContent(response);
}).then((successMsg) =>{
callback(null,successMsg);
}).catch((errMsg)=>{
callback();
});
};

Node JS Request Printing nothing in console

I'm making an post call using the nodejs requests module. However, the console.log statements seems to be not working for either the error or the response.body that I am trying to get.
My POST request needs the following headers -
Accept : "application/json"
Content-Type : "application/json"
Authorization : Basic + Base64Encoded(username+password)
The post body is something like this
Body:
{
"arg_1" : "a_string_key"
, "arg_2" : "a_string"
, "arg_3" : "a_string"
, "arg_4" : "some_value"
, "arg_5" : "some_string"
, "arg_6" : "<yyyy-mm-dd>"
, "arg_7" : "<yyyy-mm-dd>"
}
My code does nothing but send a POST request and checks if the response.statusCode ==200
Here is what I am doing
var int_user = "username";
var int_pass = "password";
var encoding = "base64"
var auth = "Basic" + new Buffer(int_user + int_pass).toString(encoding);
var headers = {
"Accept": "application/json",
"Content-Type": "application/json",
"Authorization": auth
}
var options = {
url: 'URL_I_WANT',
// method: 'POST',
headers: headers,
body : {
"arg_1": "a_string_key",
"arg_2": "a_string",
"arg_3": "a_string",
"arg_4": "some_value",
"arg_5": "some_string",
"arg_6": "<yyyy-mm-dd>",
"arg_7": "<yyyy-mm-dd>"
},
json: true
}
console.log('Before request');
request.post(options, function(error, response) {
if (error) {
console.log(error);
}
try {
if (!error && response.statusCode == 200) {
console.log(response.body);
console.log('Success');
}
} catch (error) {
console.log(error)
}
});
console.log('After request');
The code runs without any glitch and I get the before and after request console statements. However the statements inside the requests do not appear in the console, which means my request is not going through. I am not able to understand this. Shouldn't an error come if there is an issue with the request itself? Any if the request is failing, why isn't the error printed out?
This could be because your node process is auto-closed and it will exit before the async request to finishes (haven't looked into it but it might be something configurable). I've seen such set-up on repl.it for example.
To overcome this(if not configurable), you could wrap your code in an async function and use the request-promise to call await request.
var request = require('request-promise-native');
var int_user = "username";
var int_pass = "password";
var encoding = "base64"
var auth = "Basic" + new Buffer(int_user + int_pass).toString(encoding);
var headers = {
"Accept": "application/json",
"Content-Type": "application/json",
"Authorization": auth
}
var options = {
url: 'https://google.com',
method: 'POST',
headers: headers,
body : {
"arg_1": "a_string_key",
"arg_2": "a_string",
"arg_3": "a_string",
"arg_4": "some_value",
"arg_5": "some_string",
"arg_6": "<yyyy-mm-dd>",
"arg_7": "<yyyy-mm-dd>"
},
json: true
};
console.log('Before request');
async function main() {
try {
const response = await request.post(options);
if (response.statusCode === 200) {
console.log(response.body);
console.log('Success');
process.exit();
}
console.log(`Bad statusCode:${response.statusCode}`);
}
catch (error) {
console.log(error);
}
}
main();
you can check-out the code below
a link to the code above, working on repl.it

Query ElasticSearch on Node.js with HTTP module Ignores Request Body

StackOverflow community. I've started to play with ES and Node.js, and right now I'm trying to query my ES instance using the HTTP module.
I'm trying to mimic the following curl GET request:
curl -XGET 'localhost:9200/_search?pretty' -H 'Content-Type: application/json' -d'
{
"query": {
"multi_match" : {
"query": "this is a test",
"fields": [ "subject", "message" ]
}
}
}
'
like this:
var options = {
hostname: '127.0.0.1',
port: 9200,
method: 'GET',
path: '/twitter/tweet/_search?pretty',
headers: {
'Content-Type': 'application/json',
'accept': 'application/json'
},
json: query
body: {
"query": {
"multi_match" : {
"query": "this is a test",
"fields": [ "subject", "message" ]
}
}
}
};
var req = http.request(options, function (response) {
var responseBody = "";
response.setEncoding("UTF-8");
response.on('data', function (chunk) {
responseBody += chunk;
});
response.on("end", function() {
fs.writeFile("responseBody.json", responseBody, function(err) {
if (err) {
throw err;
}
});
});
});
req.on("error", function(err) {
console.log(`problem with request: ${err.message}`);
});
req.end();
But ES is returning ALL the records (like if I was hitting the _all field), not just the hits for the query I'm passing. It's like if the request body is being ignored.
I've also tried to pass it by saving the query in a variable, and the simply put in in the json key:
json: query
But the result is the same. If I enclose the json with single quotes, I get the "unexpected token" error when trying to run the app, so I'm lost on what to do to succesfully pass a query to Node.js with the HTTP module :S.
EDIT:
The solution is to pass the query (JSON stringified) in the request.write method:
req.write(query);
The whole request should look like this:
var query = JSON.stringify({
"query": {
"multi_match" : {
"query": "this is a test",
"fields": [ "subject", "message" ]
}
}
});
var options = {
hostname: '127.0.0.1',
port: 9200,
method: 'GET',
path: '/twitter/tweet/_search?pretty',
headers: {
'content-length': Buffer.byteLength(query),
'Content-Type': 'application/json'
}
};
var req = http.request(options, function (response) {
var responseBody = "";
response.setEncoding("UTF-8");
response.on('data', function (chunk) {
responseBody += chunk;
});
response.on("end", function() {
fs.writeFile("responseBody.json", responseBody, function(err) {
if (err) {
throw err;
}
});
});
});
req.on("error", function(err) {
console.log(`problem with request: ${err.message}`);
});
req.write(query);
req.end();
So the GET request of the http.request won't respect the body, it will always ignore the request body. So, you should send a POST request if you want to send body to the elasticsearch.
The elasticsearch handles both POST and GET call in the same manner.

Resources