How to do request HTTP Digest auth with Node.JS? - node.js

I have to write some code with Node.JS for an API documentation, but I tried the last few days all the solutions I could found on the web (including Stack of course) without succes...
My API use HTTP Digest Auth and that's the problem, I was able to connect, that's was not a big deal but everytime I got the same return :
Got response : 401
HTTP Digest Authentication required for "api.example.com"
You can show my base code below without auth! Because I don't know what I can do after all the try I did :
var http = require('http')
var options = {
host: 'api.example.com',
path: '/example/1.xml',
};
var request = http.get(options, function(res){
var body = "";
res.on('data', function(data){
body += data;
})
res.on('end', function(){
console.log('Got response : ' + res.statusCode);
console.log(body);
})
res.on('error', function(e){
console.log('Got error : ' +e.message);
});
});
One of my last try was to use this module https://npmjs.org/package/request but he doesn't work too as everytime I got 401 !
For more information I was able to connect and GET the information I needed from my API with Ruby, Python, php, and Java so I'm sure my API is working well and the information I pass are correct.
I use the last stable of Node v0.10.11 !
If someone can help me or have a solution up to date i will be glad.
EDIT :
I will add some details about my test with the module Mickael/request
First Try :
var request = require('request')
var options = {
'url': 'http://api.example.fr/example/1.xml',
'auth': {
'user': 'test',
'pass': 'test',
'sendImmediately': false
}
};
var request = request.get(options, function(error, response, body){
if (!error && response.statusCode == 200){
console.log('body : ' + body)
}
else{
console.log('Code : ' + response.statusCode)
console.log('error : ' + error)
console.log('body : ' + body)
}
});
Second Try :
var request = require('request')
request.get('http://api.example.fr/example/1.xml', function(error, response, body){
if (!error && response.statusCode == 200){
console.log('body : ' + body)
}
else{
console.log('Code : ' + response.statusCode)
console.log('error : ' + error)
console.log('body : ' + body)
}
}).auth('test', 'test', false);
but the return is still the same 401

Here's your example corrected to use request as per it's API.
var options = {
uri: 'http://api.example.fr/example/1.xml',
auth: {
user: 'test',
pass: 'test',
sendImmediately: false
}
};
request(options, function(error, response, body){
if (!error && response.statusCode == 200){
console.log('body : ' + body)
}
else{
console.log('Code : ' + response.statusCode)
console.log('error : ' + error)
console.log('body : ' + body)
}
});
The request chainable style API is a bit confusing (IMHO), but I believe you can make it work that way as well.

The digest auth in the request package seems to be incomplete.
You can try out: https://npmjs.org/package/http-digest-client ,its a pretty decent lightweight implementation for the digest authentication.
If you need to do a digest auth POST with a body message to be sent you can use request in conjunction with http-digest-client. After installing both just open up http-digest-client code under node-modules and replace its use of the http package with the request package api.

Try urllib it will work with simple and disgest auth.
const httpClient = require('urllib');
const url = 'https://site.domain.com/xmlapi/xmlapi';
const options = {
method: 'POST',
rejectUnauthorized: false,
// auth: "username:password" use it if you want simple auth
digestAuth: "username:password",
content: "Hello world. Data can be json or xml.",
headers: {
//'Content-Type': 'application/xml' use it if payload is xml
//'Content-Type': 'application/json' use it if payload is json
'Content-Type': 'application/text'
}
};
const responseHandler = (err, data, res) => {
if (err) {
console.log(err);
}
console.log(res.statusCode);
console.log(res.headers);
console.log(data.toString('utf8'));
}
httpClient.request(url, options, responseHandler);

your sample is work
var request = require('request')
request.get('http://api.example.fr/example/1.xml', function(error, response, body){
if (!error && response.statusCode == 200){
console.log('body : ' + body)
}
else{
console.log('Code : ' + response.statusCode)
console.log('error : ' + error)
console.log('body : ' + body)
}
}).auth('test', 'test', false);

Related

How can I send my username and password to a server when requesting it for some data?

I want to retrieve some data from a server and when I visit the server's site, I am prompted for my username and password like in the image attached.
I want to write some code that will do this for me. However, I have not found a solution that works.
I've tried the request and node-fetch modules with no success.
var url = 'http://' + username + ':' + password + '#some.server.com/data';
request({url: url}, function (error, response, body) {
console.log('error:', error); // Print the error if one occurred
console.log('statusCode:', response && response.statusCode); // Print the
response status code if a response was received
console.log('body:', body); // Print the HTML for the Google homepage.
});
var auth = "Basic " + new Buffer(username + ":" + password).toString("base64");
request(
{
url : url,
headers : {
"Authorization" : auth,
'sendImmediately': false
}
},
function (error, response, body) {
// Do more stuff with 'body' here
console.log('error:', error); // Print the error if one occurred
console.log('statusCode:', response && response.statusCode); // Print the response status code if a response was received
console.log('body:', body); // Print the HTML
}
);
fetch('some.server.com/data',
{
method: 'GET',
credentials: 'same-origin',
redirect: 'follow',
agent: null,
headers: {
'Authorization': auth,
},
timeout: 5000
})
.then(function(response){
return response.text();
})
.then(function(text){
console.log('Request success: ' + text);
})
.catch(function(error) {
console.log('Request error: ' + error);
});
How can I insert the username and password within the code so that the data retrieval process is automated? Can anyone guide me in the right direction?
Thanks.
If you're sure you're using Basic Auth then try this
request(
{
url : url,
auth: { <============ This
user: username,
password: password
}
},
function (error, response, body) {
// Do more stuff with 'body' here
console.log('error:', error); // Print the error if one occurred
console.log('statusCode:', response && response.statusCode); // Print the response status code if a response was received
console.log('body:', body); // Print the HTML
}
);

Connect https using nodejs

I am trying to maintain some old Node js code. I am having trouble in connecting to https url using corporate proxy.
Below code doesn't seem to work.
var https = require('https');
var options = {
hostname: 'PROXY_IP',
port : PROXY_PORT,
path : 'https://server.ourdomain.com/path/to/secure/api',
rejectUnauthorized : false,
headers: {
'Authorization': 'Basic ' + new Buffer('username:password').toString('base64'),
'Content-Type': 'application/json',
'Host' : 'https://server.ourdomain.com:443'
}
}
var responseChunk = '';
callback = function(response) {
if(response.statusCode !== 200) {
//Error occured. Handle error
}
response.on('data', function (chunk) {
responseChunk += chunk;
});
response.on('end', function () {
// Got complete response. Process and do something
});
}
var get_req = https.request(options, callback);
get_req.on('error', function(e) {
console.log("Error:" + e)
});
get_req.end();
Error after executing this is
Error:Error: socket hang up
I was able to get this working using request module. But not using https module.
What seems to be the problem?
Use request..
var request = require('request');
request({'url':'https://anysite.you.want/sub/sub','proxy':'http://yourproxy:8087'}, function (error, response, body) {
if (!error && response.statusCode == 200) {
console.log(body);
}
})

Slack no payload received nodejs

SO using curl I can successfully send post request to slack
curl -X POST --data-urlencode 'payload={"channel": "#tech-experiment", "username": "at-bot", "text": "This is posted to #general and comes from a bot named webhookbot.", "icon_emoji": ":ghost:"}' https:/company.slack.com/services/hooks/incoming-webhook?token=dddddddd2342343
however when I converted it to code using nodejs
var request = require('request');
var http = require('http');
var server = http.createServer(function(req, response){
response.writeHead(200,{"Content-Type":"text/plain"});
response.end("end");
});
option = {
url: 'https://company.slack.com/services/hooks/incoming-webhook?token=13123213asdfda',
payload: '{"text": "This is a line of text in a channel.\nAnd this is another line of text."}'
}
request.post(
option,
function (error, response, body) {
if (!error && response.statusCode == 200) {
console.log(body)
}else {
console.log('wtf')
console.log(response.statusCode)
console.log(response)
console.log(error)
}
}
);
it throws status 500. can anyone help?
i reviewed the token
also done my research but nothing is working..
I appreciate all your help
You need to use the https library, since the server requests are on a different port. You current code is sending the request to port 80 instead of port 443. This is some sample code I built for an integration.
var https = require( 'https' );
var options = {
hostname : 'company.slack.com' ,
path : '/services/hooks/incoming-webhook?token=rUSX9IyyYiQmotgimcMr4uK8' ,
method : 'POST'
};
var payload1 = {
"channel" : "test" ,
"username" : "masterbot" ,
"text" : "Testing the Slack API!" ,
"icon_emoji" : ":ghost:"
};
var req = https.request( options , function (res , b , c) {
res.setEncoding( 'utf8' );
res.on( 'data' , function (chunk) {
} );
} );
req.on( 'error' , function (e) {
console.log( 'problem with request: ' + e.message );
} );
req.write( JSON.stringify( payload1 ) );
req.end();
I think it is not payload but form.
This code succeed in calling Incoming Webhooks.
var request = require('request');
var options = {
uri: "https://hooks.slack.com/services/yourURI",
form: '{"text": "This code..."}'
};
request.post(options, function(error, response, body){
if (!error && response.statusCode == 200) {
console.log(body.name);
} else {
console.log('error: '+ response.statusCode + body);
}
});
wanted to chime in, as I found this while also trying to do the same thing. I ended up doing this:
got('https://hooks.slack.com/services/[your configured url]', {
method: 'POST',
body: JSON.stringify({
"text": "message" + variable
})
});
Either use form in your option object or set a body parameter along with the 'content-type' set to 'application/x-www-form-urlencoded'. Here's a working example.
var payload = JSON.stringify(payload)
request.post({
headers: {'content-type' : 'application/x-www-form-urlencoded'},
url: 'Your Webhook URL',
body: "payload="+payload
}, function(error, response, body){
if(error){
console.log(error);
}
console.log(body);
});

Postpone responding to request in Node.js

When my Node.js Express server, which is listening on port 3000, receives a request, it routes to a function that must issue a POST to another Web site and get the response before responding to the initial request.
Is that possible?
Here is the code I'm using:
app.get('/silence/:host', routes.silence);
http.createServer(app).listen(app.get('port'), function(){
console.log('Express server listening on port ' + app.get('port'));
});
exports.silence = function(request, response){
var hostname = utils.validateHost(request);
if (stash.createSilencer(hostname)) {
response.writeHead(200, {"Content-Type": "application/json"});
response.write('{ "success" : true, "message" : "Successfully silenced host'" }');
response.end();
}
}
exports.createSilencer = function(hostname) {
var options = {
url: 'http://x.x.com:4567/create/silencer/' + hostname ,
method: 'POST',
body: '{ "timestamp": ' + utils.timestamp() + '} '
};
request(options, silencer_callback);
##### DONT WANT TO RETURN UNTIL THE silencer_callback IS INVOKED
return true;
}
function silencer_callback(error, response, body) {
if (!error && response.statusCode == 200) {
var info = JSON.parse(body);
console.log("Response Recieved");
}
}
The trick is that you don't call response.write() and response.end() until you receive a response from you POST request. You just exit the method without sending response back. Once you have result from your POST request, you can finish initial response.
exports.silence = function(req, res){
var hostname = utils.validateHost(req);
stash.createSilencer(hostname, function(error, response, body) {
if (!error && response.statusCode == 200) {
var info = JSON.parse(body);
console.log("Response Received");
}
// we get POST-response, lets response to initial request here
res.writeHead(200, {"Content-Type": "application/json"});
res.write('{ "success" : !error, "message" : "Successfully silenced host'" }');
res.end();
});
// return from the function, but do not send response back yet
}
exports.createSilencer = function(hostname, callback) {
var options = {
url: 'http://x.x.com:4567/create/silencer/' + hostname ,
method: 'POST',
body: '{ "timestamp": ' + utils.timestamp() + '} '
};
request(options, callback);
// return from the function, but do not send response back yet
}

how to do Auth in node.js client

I want to get use this rest api with authentication. I'm trying including header but not getting any response. it is throwing an output which it generally throw when there is no authentication. can anyone suggest me some solutions. below is my code
var http = require('http');
var optionsget = {
host : 'localhost', // here only the domain name
port : 1234,
path:'/api/rest/xyz',
headers: {
'Authorization': 'Basic ' + new Buffer('abc'+ ':' + '1234').toString('base64')
} ,
method : 'GET' // do GET
};
console.info('Options prepared:');
console.info(optionsget);
console.info('Do the GET call');
var reqGet = http.request(optionsget, function(res) {
console.log("statusCode: ", res.statusCode);
res.on('data', function(d) {
console.info('GET result:\n');
process.stdout.write(d);
console.info('\n\nCall completed');
});
});
reqGet.end();
reqGet.on('error', function(e) {
console.error(e);
});
The request module will make your life easier. It now includes a Basic Auth as an option so you don't have build the Header yourself.
var request = require('request')
var username = 'fooUsername'
var password = 'fooPassword'
var options = {
url: 'http://localhost:1234/api/res/xyz',
auth: {
user: username,
password: password
}
}
request(options, function (err, res, body) {
if (err) {
console.dir(err)
return
}
console.dir('headers', res.headers)
console.dir('status code', res.statusCode)
console.dir(body)
})
To install request execute npm install -S request
In your comment you ask, "Is there any way that the JSOn I'm getting in the command prompt will come in the UI either by javascript or by Jquery or by any means."
Hey, just return the body to your client:
exports.requestExample = function(req,res){
request(options, function (err, resp, body) {
if (err) {
console.dir(err)
return;
}
// parse method is optional
return res.send(200, JSON.parse(body));
});
};

Resources