Using http.request in Node.JS while passing an API key - node.js

I am currently fiddling around with Node.JS to try to create a package for PostageApp to be able to send emails through our API.
To start, I am using the following code to test out how Node.JS can best interface with our API, but it doesn't seem to want to pass along the API key that I have attached as part of the headers.
var http = require('http');
function onRequest(request, response) {
response.end();
}
http.createServer(onRequest).listen(8888);
console.log("Server has started.");
var options = {
host: 'api.postageapp.com',
path: '/v.1.0/get_account_info.json',
method: 'POST',
headers: { "api_key" : "MY API KEY HERE" }
};
var req = http.request(options, function(res) {
console.log('STATUS: ' + res.statusCode);
res.setEncoding('utf8');
res.on('data', function (chunk) {
console.log('BODY: ' + chunk);
});
});
req.end();
console.log("Request sent!");
I pulled this together using various examples and what not - it's not pretty, I know. However, using HTTPS, I finally got it to hit our API and get a response:
{"response":{"status":"unauthorized","message":"Invalid or inactive API key used","uid":null}}
The only conclusion I can come up with is that the API key is not getting passed along, and I would appreciate any help as to how to make that happen.
Thanks!

Here's an example of code I have used to call web APIs with a key in the header:
var api = http.createClient(80, 'api.example.org');
var request = api.request('GET', '/api/foo',
{
'host': 'api.example.org',
'accept': 'application/json',
'api-key': 'apikeygoeshere'
});
request.on('response', function (response) {});
request.end();

Related

DELETE request to REST API returns 500

function delete(id, response) {
var https = require('https');
var linkpath = "/v1/endpoint/" + id + "/?token=" + AUTH_KEY;
var req = https.request({
hostname: 'api.foo.com',
port: 443,
path: linkpath,
agent: false,
method: 'DELETE',
}, (res) => {
if (res.statusCode !== 200) {
response.send('HTTP ' + res.statusCode + ' ' + res.statusMessage);
}
res.on('error', function (err) {
response.send(err);
});
res.on('end', function (data) {
response.send(data);
});
});
req.on('error', function(e) {
response.send(e.message);
});
req.end();
}
This code, adapted from my (working) code that uses a POST request to do other things with this API, nets me a status code of 500 from the endpoint.
I don't know how to debug this. I can't send the URL manually to the server because it's a DELETE operation instead of a GET or POST.
Has anyone seen this problem? Or do you have ideas on how to debug it?
Postman (https://www.getpostman.com/) is a great tool for manually sending specific HTTP requests, including DELETE!
There are all sorts of tools that will let you manually send any HTTP to the server. For instance, you can get quite a bit of information with curl, which will happily send a DELETE request.
For example:
curl -v -X "DELETE" https://jsonplaceholder.typicode.com/posts/1
will return the request and response headers as well as the body of the return value if any.

Using Bulit-in Http Module instead of Request Module on Node.js

I want to send form data to web-server by using Node.js, So I use "request" module that is very famous in nodeland. And It's cool, There is no problem, But because of some reason (write-stream encoding non-supported), I have to change it to built-in module, "http".
I think beneath codes are same to post some data to web-server, When I using "request" module, There is no problem so can get 200 response, success to sending data.
But in "http" module, I got a 302 response that redirects to another page. and failed post data. I don't know what is problem with, maybe it is something URL trouble, http use 'host and path' on the other hand, request use 'url' . I don't know how can I solve this, I stucked 2 days, please let me know If you have some hints..
Thanks.
By Using "Request" Module
function postFormByRequestModule() {
request({
url: 'http://finance.naver.com/item/board_act.nhn',
headers: { 'Content-Type': 'text/plain' },
method: 'POST',
form: {
code:'000215',
mode: 'write',
title: 'This is Title',
body:'This is body'
}
}, function (error, response, body) {
if (error) {
console.log(error);
} else {
console.log(response.statusCode, response.body);
}
});
}
By Using "Http" Module
var postData = querystring.stringify({
code:'000215',
mode: 'write',
title: 'This is Title',
body:'This is body'
});
var options = {
host: 'finance.naver.com',
path: '/item/board_act.nhn',
method: 'POST',
headers: { 'Content-Type': 'text/plain', }
};
var req = http.request(options, function(res) {
console.log('STATUS: ' + res.statusCode);
res.setEncoding('utf8');
res.on('data', function (chunk) {
console.log('BODY: ' + chunk);
});
res.on('end', function() {
console.log('No more data in response.')
})
});
req.on('error', function(e) {
console.log('problem with request: ' + e.message);
});
function postFormByBuiltInHttpModule() {
req.write(postData);
req.end();
}
The built-in http client does not automatically follow forwards, whereas the request module does (and has many other "high level" features). So if you want to continue using the built-in client, you will need to manually check res.headers.location and retry the request at that url.

Setting request headers in Node.js

I have been working with node.js to set up a proxy server that will handle incoming client request and will verify that they have the proper certificates to get connected to the server.
What I want to do is to be able to add the client's certificate to their header to craft a user name, that I will pass on to the server.
function (req, res) {
//Here is the client certificate in a variable
var clientCertificate = req.socket.getPeerCertificate();
// Proxy a web request
return this.handle_proxy('web', req, res);
};
What I want to be able to do is this : req.setHeader('foo','foo')
I know that the proxy.on('proxyReq) exist, but the way the code is set up, I need to be able to use the req parameter.
Is there a way to do this?
Please let me know if I need to clarify my question.
You can craft your own http request with the headers provided in the original request plus any extra headers that you'd like by using http.request. Just receive the original request, copy the headers into the new request headers, add the new headers and send the new request.
var data = [];
var options = {
hostname: 'www.google.com',
port: 80,
path: '/upload',
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Content-Length': postData.length
}
};
var req = http.request(options, function(res) {
res.setEncoding('utf8');
res.on('data', function (chunk) {
data.push(chunk);
});
res.on('end', function() {
console.log(data.join(""));
//send the response to your original request
});
});
req.on('error', function(e) {
console.log('problem with request: ' + e.message);
});
// Set headers here i.e. req.setHeader('Content-Type', originalReq.getHeader('Content-Type'));
// write data to request body
req.write(/*original request data goes here*/);
req.end();

How to access response Body after simulating a POST request in Node.js?

I have been trying this out for a long time now.
I want to scrap contents from a subreddit that has adult contents.
But, the problem is that, you have to answer a simple question before you are given access to that page i.e. if you are 18+ or not.
I did some research on the source code and found that the solution is a simple POST request. where you need to send the parameters "over18=yes".
But my problem is that, I am not able to access the response body after the post.
Here's the code using http request in node. I have even tried it out with the node "request" module, but no help from that either.
Hoping to find someone who can help me out here.
var http = require("http");
var options = {
host: 'www.reddit.com',
port: 80,
path: '/over18?dest=http%3A%2F%2Fwww.reddit.com%2Fr%2Fnsfw&over18=yes',
method: 'POST'
};
var req = http.request(options, function(res) {
console.log('STATUS: ' + res.statusCode);
console.log('HEADERS: ' + JSON.stringify(res.headers));
res.setEncoding('utf8');
res.on('data', function (chunk) {
console.log('BODY: ' + chunk);
});
});
req.on('error', function(e) {
console.log('problem with request: ' + e.message);
});
// write data to request body
req.write('data\n');
req.write('data\n');
req.end();
And here is the code using the Node Request module
var request = require("request");
request.post({url:'http://www.reddit.com/over18?dest=http%3A%2F%2Fwww.reddit.com%2Fr%2Fnsfw', form: {over18:'yes'}}, function(err,httpResponse,body){
console.log(body);
});
the URL i am trying to access is http://www.reddit.com/r/nsfw
In short, when you click YES button, the form sends over18=yes parameter to url http://www.reddit.com/over18?dest=http%3A%2F%2Fwww.reddit.com%2Fr%2Fnsfw using POST method. Then, server responds with an 302 Redirection header, cookie with value over18=1 and finally redirects to url http://www.reddit.com/r/nsfw using GET request. THen, server just checks if youa have a cookie with needed valuse.
All what you need is to do request directly to the final url with cookies using GET method.
var request = require("request");
var target = "http://www.reddit.com/r/nsfw";
var jar = request.jar();
var cookie = request.cookie("over18=1");
cookie.domain = "reddit.com";
cookie.path = "/";
jar.setCookie(cookie, target, function(error, cookie) {
console.log(error);
console.log(cookie);
});
request({
uri: target,
method: "GET",
jar: jar
}, function(error, response, body) {
console.log(response.statusCode);
console.log(body);
});
I too ran into this while ahem doing some research.. Here's my version:
var url = 'http://www.reddit.com/r/nsfw/';
var request = require('request');
request = request.defaults({jar: true });
request.post({
followAllRedirects: true,
url: 'http://www.reddit.com/over18?dest=' + encodeURIComponent(url),
form: {uh: '', over18: 'yes', }
}, function(err, httpResponse, html) {
…
});
Also worth a try are Reddit's Node.js APIs, of which I personally liked Snoocore.

Sending data through POST request from a node.js server to a node.js server

I'm trying to send data through a POST request from a node.js server to another node.js server. What I do in the "client" node.js is the following:
var options = {
host: 'my.url',
port: 80,
path: '/login',
method: 'POST'
};
var req = http.request(options, function(res){
console.log('status: ' + res.statusCode);
console.log('headers: ' + JSON.stringify(res.headers));
res.setEncoding('utf8');
res.on('data', function(chunk){
console.log("body: " + chunk);
});
});
req.on('error', function(e) {
console.log('problem with request: ' + e.message);
});
// write data to request body
req.write('data\n');
req.write('data\n');
req.end();
This chunk is taken more or less from the node.js website so it should be correct. The only thing I don't see is how to include username and password in the options variable to actually login. This is how I deal with the data in the server node.js (I use express):
app.post('/login', function(req, res){
var user = {};
user.username = req.body.username;
user.password = req.body.password;
...
});
How can I add those username and password fields to the options variable to have it logged in?
Thanks
Posting data is a matter of sending a query string (just like the way you would send it with an URL after the ?) as the request body.
This requires Content-Type and Content-Length headers, so the receiving server knows how to interpret the incoming data. (*)
var querystring = require('querystring');
var http = require('http');
var data = querystring.stringify({
username: yourUsernameValue,
password: yourPasswordValue
});
var options = {
host: 'my.url',
port: 80,
path: '/login',
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Content-Length': Buffer.byteLength(data)
}
};
var req = http.request(options, function(res) {
res.setEncoding('utf8');
res.on('data', function (chunk) {
console.log("body: " + chunk);
});
});
req.write(data);
req.end();
(*) Sending data requires the Content-Type header to be set correctly, i.e. application/x-www-form-urlencoded for the traditional format that a standard HTML form would use.
It's easy to send JSON (application/json) in exactly the same manner; just JSON.stringify() the data beforehand.
URL-encoded data supports one level of structure (i.e. key and value). JSON is useful when it comes to exchanging data that has a nested structure.
The bottom line is: The server must be able to interpret the content type in question. It could be text/plain or anything else; there is no need to convert data if the receiving server understands it as it is.
Add a charset parameter (e.g. application/json; charset=Windows-1252) if your data is in an unusual character set, i.e. not UTF-8. This can be necessary if you read it from a file, for example.
You can also use Requestify, a really cool and very simple HTTP client I wrote for nodeJS + it supports caching.
Just do the following for executing a POST request:
var requestify = require('requestify');
requestify.post('http://example.com', {
hello: 'world'
})
.then(function(response) {
// Get the response body (JSON parsed or jQuery object for XMLs)
response.getBody();
});

Resources