https.request ignoring rejectUnauthorized - javascript

I'm trying to connect to a remote server using nodejs 0.12, and i keep getting the response SELF_SIGNED_CERT_IN_CHAIN. I have looked at similar questions 1 2 but somehow their solutions don't work on my server.
I am connecting to a test environment outside of my control setted up with a self signed certificate. This is my request:
var https = require("https");
var fs = require('fs');
start();
function start()
{
var listadebancos =
{
language:"es",
command:"GET_BANKS_LIST",
merchant:
{
apiLogin:"111111111111111",
apiKey:"11111111111111111111111111",
},
test:true,
bankListInformation:
{
paymentMethod:"PSE",
paymentCountry:"CO"
}
};
var listadebancosString = JSON.stringify(listadebancos);
var headers =
{
'Content-Type': 'application/json',
'Content-Length': listadebancosString.length
};
var options= {
host: 'stg.api.payulatam.com',
rejectUnauthorized: false,
agent:false,
path: '/payments-api/4.0/service.cgi',
method: 'POST',
cert: fs.readFileSync('./stg.gateway.payulatam.crt'),
}
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
var req= https.request(options, funcionRespuesta);
req.write(listadebancosString);
req.end();
function funcionRespuesta(res)
{ console.log(res);
}
}
Am i missing something obvious?

I decided to use a library call needle to make the request and this time i was able to receive the response with no SSL errors. Just in case anyone is in the same situation here is the code i used:
var listadebancos =
{
"language":"es",
"command":"GET_BANKS_LIST",
"merchant":{
"apiLogin:"111111111111111",
"apiKey:"11111111111111111111111111",
},
"test":false,
"bankListInformation":{
"paymentMethod":"PSE",
"paymentCountry":"CO"
}
};
};
// var listadebancosString = JSON.stringify(listadebancos);
var headers =
{
'Content-Type': 'application/json'
};
var options = {
host: 'stg.api.payulatam.com',
**json:true,**
path: '/payments-api/4.0/service.cgi',
method: 'GET',
headers: headers,
rejectUnauthorized: false,
requestCert: true,
agent: false,
strictSSL: false,
}
needle
.post('stg.api.payulatam.com/payments-api/4.0/service.cgi',listadebancos, options, funcionRespuesta)
.on('end', function() {
console.log('Ready-o, friend-o.');
})
function funcionRespuesta(err, resp, body)
{
console.log(err);
console.log(body);
}

Related

https.request inside await fetch not working

I have some code that looks like this in Next JS
const resApp = await fetch('/api/club/createsignalapp', {
body: JSON.stringify({
name: event.target.name.value,
}),
headers: {
'Content-Type': 'application/json',
},
method: 'POST',
})
const appResult = await resApp.json()
--createsignalapp
export default async (req, res) => {
var mydata
var createApp = function (data) {
var headers = {
'Content-Type': 'application/json; charset=utf-8',
Authorization: `Basic APIKKEY`,
}
var options = {
host: 'onesignal.com',
port: 443,
path: '/api/v1/apps',
method: 'POST',
headers: headers,
}
var https = require('https')
var myreq = https.request(options, function (myres) {
myres.on('data', function (data) {
mydata = JSON.parse(data)
res.statusCode = 200
res.json({
response: {
boolean: true,
alert: '',
message: '',
},
data: mydata
})
})
})
myreq.on('error', function (e) {
console.log(e)
})
myreq.write(JSON.stringify(data))
myreq.end()
}
var message = {
name: req.body.name
}
createApp(message)
}
This hits the error API resolved without sending a response for /api/club/createsignalapp, this may result in stalled requests.
I'm not sure how to do this correctly as i'm getting confused with the awaits and asyncs and requests everywhere.
Happy to hear suggestions.
Thanks

How to combine API GET request in nodejs?

I have several API Get request at once in nodejs. Each API have new data every couple minutes.
var express = require('express');
var router = express.Router();
var request = require("request");
let value1, value2, bodyData1, bodyData2;
var options = { method: 'GET',
url: 'https://api.example.com/data1',
qs:
{
valueType: 'MAXIMUM'
},
headers:
{
authorization: 'ABC123456',
accept: 'application/json; charset=utf-8' } };
request(options, function (error, response, body) {
if (error) throw new Error(error);
bodyData1 = JSON.parse(body);
value1 = bodyData1.value;
});
var options = { method: 'GET',
url: 'https://api.example.com/data2',
qs:
{
valueType: 'MAXIMUM'
},
headers:
{
authorization: 'ABC123456',
accept: 'application/json; charset=utf-8' } };
request(options, function (error, response, body) {
if (error) throw new Error(error);
bodyData2 = JSON.parse(body);
value2 = bodyData2.value;
});
router.get('/', function(req, res, next) {
res.render('home', {valueA : value1, valueB: value2});
});
module.exports = router;
I want to know if it is possible to combine them into one function?
Any other things I should concern?
It is possible if you have promises which is currently not the case. You have to wrap your request() call in a Promise. You can do it manually with a custom function requestToPromise.
You can then use Promise.all to call multiple promises in parallel.
function requestToPromise(options) {
return new Promise((resolve, reject) => {
request(options, (error, response, body) => {
if (error) return reject(error);
resolve(body);
});
});
}
var optionsRequest1 = {
method: "GET",
url: "https://api.example.com/data1",
qs: {
valueType: "MAXIMUM"
},
headers: {
authorization: "ABC123456",
accept: "application/json; charset=utf-8"
}
};
var optionsRequest2 = {
method: "GET",
url: "https://api.example.com/data2",
qs: {
valueType: "MAXIMUM"
},
headers: {
authorization: "ABC123456",
accept: "application/json; charset=utf-8"
}
};
var requestPromise1 = requestToPromise(optionsRequest1);
var requestPromise2 = requestToPromise(optionsRequest2);
Promise.all([requestPromise1, requestPromise2]).then(results => {
var [resultPromise1, resultPromise2] = results;
}).catch(error => {
//handle error
});
Instead of using the custom function requestToPromise you can also use util.promisify
const util = require('util');
const requestAsync = util.promisify(request);
Promise.all([requestAsync(optionsRequest1), requestAsync(optionsRequest2)]).then(results => {
var [resultPromise1, resultPromise2] = results;
}).catch(error => {
//handle error
});
You can use Redis cache to store data in memory for fast retrieval and fetch from memory very quickly.
Also, after some interval, you can add them to a database through bulk creation. It will decrease your database call.
// Example in sequilize
await db.table_name.bulkcreate([ {0bj1}, {obj2}..,{obj3 } ]);

How to invoke services in loop in node express?

I am trying to invoke services in node express in a loop. But the problem is that before all the services are invoked, the remaining code is getting executed.
I tried some options with Promise, async/await but they didn't work.
Basically I need to invoke the service in a synchronous way.
I have created 2 mock services in JSON stub. In the first service response, I will get an array of vehicles. Once I got this, I need to update one more value in each array by calling another service.
Here the problem I faced is that the 2nd service is not called synchronously.
const express = require('express');
const request = require("request");
const router = express.Router();
router.get('/make', (req, res) => {
var options = {
headers: {
'Content-Type': 'application/json',
'JsonStub-User-Key': 'ddc159a0-5aa8-4a38-a0f1-913e4d768b56',
'JsonStub-Project-Key': '34ba28a9-471c-435d-ab61-b7732c9583c6'
},
method: "GET",
json: true,
strictSSL : false,
url: `http://jsonstub.com/vehicle/make`
};
request(options, function(error, response, body) {
if (body){
checkModelType(body);
res.status(200).json(body).end();
} else {
console.log("REST Request timeout: ", JSON.stringify(error));
res.status(400).json('Error').end();
}
});
});
function checkModelType(response){
let vehicleList = response.vehicleList;
console.log("--->"+vehicleList.length);
for(var i = 0;i<vehicleList.length;++i){
const modelType = findModel();
vehicleList[i].modelType = modelType;
}
console.log("Updated Vehicle List:"+JSON.stringify(vehicleList));
}
const findModel = () =>{
var options = {
headers: {
'Content-Type': 'application/json',
'JsonStub-User-Key': 'ddc159a0-5aa8-4a38-a0f1-913e4d768b56',
'JsonStub-Project-Key': '34ba28a9-471c-435d-ab61-b7732c9583c6'
},
method: "GET",
json: true,
strictSSL : false,
url: `http://jsonstub.com/vehicle/details`
};
request(options, function(error, response, body) {
if (body){
console.log("Model Type-->"+body.output.modelType);
return body.output.modelType;
} else {
console.log("REST Request timeout: ", JSON.stringify(error));
}
});
}
module.exports = router;
Response :
-----------
PS F:\workSpace_Node\TestApp> node app.js
server running at 9086
--->4
Updated Vehicle List:[{"make":"Audi","model":"A3","vin":"QVFCFQT7894563214"},{"make":"Audi","model":"A4","vin":"ASECFQT7894563214"},{"make":"Audi","model":"Q5","vin":"QWECFQT7894993214"}]
Model Type-->SD
Model Type-->SD
Model Type-->SD
Expected result :
[{"make":"Audi","model":"A3","modelType":"SD", "vin":"QVFCFQT7894563214"},{"make":"Audi","model":"A4","modelType":"SD","vin":"ASECFQT7894563214"}]
You can switch to request-promise library instead of request and then go with some async\await:
const express = require('express');
const request = require('request-promise'); // switched library
const router = express.Router();
router.get('/make', async (req, res) => {
var options = {
headers: {
'Content-Type': 'application/json',
'JsonStub-User-Key': 'ddc159a0-5aa8-4a38-a0f1-913e4d768b56',
'JsonStub-Project-Key': '34ba28a9-471c-435d-ab61-b7732c9583c6'
},
method: "GET",
json: true,
strictSSL : false,
url: `http://jsonstub.com/vehicle/make`
};
const body = await request(options);
if (body) {
await checkModelType(body);
res.status(200).json(body).end();
} else {
console.log("REST Request timeout: ", JSON.stringify(error));
res.status(400).json('Error').end();
}
});
async function checkModelType(response){
let vehicleList = response.vehicleList;
console.log("--->"+vehicleList.length);
for(var i = 0;i<vehicleList.length;++i){
const modelType = await findModel();
vehicleList[i].modelType = modelType;
}
console.log("Updated Vehicle List:"+JSON.stringify(vehicleList));
}
const findModel = async () =>{
var options = {
headers: {
'Content-Type': 'application/json',
'JsonStub-User-Key': 'ddc159a0-5aa8-4a38-a0f1-913e4d768b56',
'JsonStub-Project-Key': '34ba28a9-471c-435d-ab61-b7732c9583c6'
},
method: "GET",
json: true,
strictSSL : false,
url: `http://jsonstub.com/vehicle/details`
};
const body = await request(options);
if (body){
console.log("Model Type-->"+body.output.modelType);
return body.output.modelType;
} else {
console.log("REST Request timeout: ", JSON.stringify(error));
}
}
module.exports = router;
And it will change the order of operations:
--->4
Model Type-->SD
Model Type-->SD
Model Type-->SD
Model Type-->SD
Updated Vehicle List:[{"make":"Audi","model":"A3","vin":"QVFCFQT7894563214","modelType":"SD"},{"make":"Audi","model":"A4","vin":"ASECFQT7894563214","modelType":"SD"},{"make":"Audi","model":"Q7","modelType":"SD"},{"make":"Audi","model":"Q5","vin":"QWECFQT7894993214","modelType":"SD"}]

How to use the requestJS get method to set the cookie?

let headers = {
'Accept': xxxxx,
'Host': 'xxxx',
'Referer': 'https://xxxx/',
}
request.get(url, {
json: true,
headers: headers
}).on('response', function (response) {
let headers = response.headers['set-cookie'];
})
If I use
headers = {
'Accept': xxx,
'cookie':xxx
}
it will memory leak
According to the README of request, you can use request.jar() to set your own cookie to the request.
var j = request.jar();
var cookie = request.cookie('key1=value1');
var url = 'http://www.google.com';
j.setCookie(cookie, url);
request({url: url, jar: j}, function () {
request('http://images.google.com')
})
UPDATE:
They said,
Cookies are disabled by default (else, they would be used in subsequent requests). To enable cookies, set jar to true (either in defaults or options).
So you can enable request to use cookies just to set { jar: true }.
var request = request.defaults({jar: true})
request('http://www.google.com', function () {
request('http://images.google.com')
})

How to send cookies with node-fetch?

I've got nodejs application which handles user's requests and receives cookies which i want to proxy to internal API service. How to approach this by using node-fetch?
Don't offer superagent please.
You should be able to pass along cookies by setting it in the header of your request:
const opts = {
headers: {
cookie: 'accessToken=1234abc; userId=1234'
}
};
const result = await fetch(`/some/url`, opts);
Read & write cookies like a bot
async function login() {
return fetch('<some_url>/login', {
'headers': {
'accept': '*/*',
'content-type': 'application/x-www-form-urlencoded; charset=UTF-8',
'cookie': '',
},
'body': 'username=foo&password=bar',
'method': 'POST',
});
}
(async() => {
const loginResponse = await login();
const loginCookies = parseCookies(loginResponse);
})();
You may want to include: accept-language, user-agent, referer, accept-encoding, etc. (check a sample request on your Chrome DevTools via the Network tab)
For some reason the resulting cookies of node-fetch requests are not compatible with new requests, but we can parse them like this:
function parseCookies(response) {
const raw = response.headers.raw()['set-cookie'];
return raw.map((entry) => {
const parts = entry.split(';');
const cookiePart = parts[0];
return cookiePart;
}).join(';');
}
Pass cookies in your future requests through the same headers:
return fetch('<some_url>/dashboard', {
'headers': {
'accept': '*/*',
'cookie': parsedCookies,
},
'method': 'GET',
});
For simple, you can write a middleware which will include the cookies to global.fetch, like below.
const realFetch = fetch;
function cookieFetch(fetch, cookie) {
return (url, opts) => {
opts = opts || {};
return fetch(url, Object.assign(opts, {
headers: Object.assign(opts.headers || {}, { cookie })
}));
};
}
function middleware(req, res, next) {
const kuki = req.headers.cookie;
global.fetch = kuki ?
cookieFetch(realFetch, kuki) :
realFetch;
next();
}
module.exports = middleware;

Categories