IIS authentication for http request with Nodejs - node.js

I have one problem with HTTP GET/POST request.
When I use the DHC/Postman, send the parameters to the URL + endpoint, works perfectly. 200 is returned.
But with code, like my example, show one 401 error.
I have searched about that and the problem is with the auth, not sure, see... Maybe is the same.
With this explanation, need to set the Authorization, I think. But the problem is when I access the site, the auth is automatic, see:
My code:
var jsonObject = JSON.stringify({ "UserName": login});
// prepare the header
var postheaders = {
'Content-Type' : 'application/json',
'Content-Length' : Buffer.byteLength(jsonObject, 'utf8')
};
// the post options
var optionspost = {
host: "xxxxxxxxxx.com",
// path: '/Home/endpoint', //send the data for the endpoit with Postma works fine
method: 'POST',
headers : postheaders
};
console.info('Options prepared:');
console.info(optionspost);
console.info('Do the POST call');
// do the POST call
var reqPost = http.request(optionspost, function(res) {
console.log("statusCode: ", res.statusCode);
// uncomment it for header details
// console.log("headers: ", res.headers);
res.on('data', function(d) {
console.info('POST result:\n');
process.stdout.write(d);
console.info('\n\nPOST completed');
});
});
// write the json data
reqPost.write(jsonObject);
reqPost.end();
reqPost.on('error', function(e) {
console.error(e);
});
Obs.: This website it's from my Company (.NET) and is Integrated with IIS (Active Directory login users for authenticate), when I access, automatically is logged... I really don't know how to solve this.
Obs II.: I Try to use one anonymous new tab and use DHC online, and my post doesn't work. This application just works inside network company and with Client side (Using postman with my computer).
Obs III.: The request is from Server and the login from my server have all permissions to access this site, and when I request, is like I'm anonymous, but if I did the same with REST Client/Postman, works perfectly. I need that it works with http request from my Server.

You can use a module like ntlm-webapi which will allow you to use NTLM auth. That way the request will go through. Just make sure the user you use is authorized for that server.
var Request = require('ntlm-webapi');
var request = new Request({
url: "http://some.restful.api.org/you/want/to/call",
username: 'username',
password: 'password',
domain: 'company_domain'
});
request.get(function(err, result){
if (err) console.log (err);
console.log (result);
});

It seems that you forgot to add the Authorization header in your code
// prepare the header
var postheaders = {
'Authorization' : 'Negotiate '+ yourAccessKey,
'Content-Type' : 'application/json',
'Content-Length' : Buffer.byteLength(jsonObject, 'utf8')
};

Related

Node Js access to api laravel

Hi i already have one api in laravel, but i need access with express node js.
This is my funcition
var data = querystring.stringify({
_token: 'LhTsymoueRtcWtjP69MD1KEbDyGl0NGuewWOieER',
propertiesString: properties
});
var options = {
hostname: 'apiproperties.local',
port: 80,
path: '/properties/storeSB',
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Content-Length': Buffer.byteLength(data)
}
/*headers: {
'Content-Type': 'application/json',
}*/
};
var req = http.request(options, function(res) {
res.setEncoding('utf8');
console.log('Status: ' + res.statusCode);
console.log('Headers: ' + JSON.stringify(res.headers));
res.on('data', function (chunk) {
console.log("body: " + chunk);
});
});
req.write(data);
req.end();
This give me error Illuminate/Foundation/Http/Middleware/VerifyCsrfToken.php line 68 because i dont send _token, but i dont know how send token in nodejs i not have views in nodejs because i not want to use i not need it, so how send token in my post request without call for form in one view? regards
You should exclude your api written in Laravel from CSRF Protection check middleware by default VerifyCsrfToken middleware is applied to route group web so here you are having two options :-
Create a new middleware group named api
code snippet for creating a middleware
routes.php
Route::group(['prefix' => 'api/v1','middleware' => ['api']], function () {
Route::get('/hotel/list',[
'uses' => 'YourController#function'
]);
});
VerifyCsrfToken.php
protected $except = [
'api/v1/*',
];
Directly exclude routes for CSRF check
In VerifyCsrfToken.php add all api's url which you want to ignore for CSRF check
class VerifyCsrfToken extends BaseVerifier
{
/**
* The URIs that should be excluded from CSRF verification.
*
* #var array
*/
protected $except = [
'url_regex'
];
}
First method is more suggested as for all future new routes addition would work out we just need to add that route under this middleware group.
Let me know in comments if it worked out or if have any query.

Unable to authenticate with Google token in Node JS

On a Node server, I am trying to validate a Google user but it always returns with a "Bad Request". What is wrong in my code?
var post_data = querystring.stringify({
'alt': 'json',
'access_token': <token from REST API params>
});
var post_options = {
host: 'www.googleapis.com',
port: '443',
path: '/oauth2/v1/userinfo',
method: 'GET',
headers: {
'Content-Length': Buffer.byteLength(post_data)
}
};
var post_req = https.request(post_options, function (result) {
if (result.statusCode == 200) {
result.on('data', function (chunk) {
//Valid user stuff
});
}
else {
//Invalid user stuff
}
});
post_req.write(post_data);
post_req.end();
The scenario here is that my client app is a chrome extension that successfully gets a token. The token is passed to my REST API hosted on the Node server. I try to replay that token to authenticate the Google user. (Note that if I use the token on the Chrome extension to make the same request, it succeeds and I get the profile information! It's only the request on the Node server that fails.) Help me! Please?
The problem is that you are:
Using the property host instead of hostname
Providing the port parameter (not sure about this one, but it will work without it)
Method should be POST, not GET
So, your new post_options object should be:
var post_options = {
hostname: 'www.googleapis.com',
path: '/oauth2/v1/userinfo',
method: 'POST',
headers: {
'Content-Length': Buffer.byteLength(post_data)
}
};
If you want to make it easier on yourself you could use a module such as google-auth-library or google-sign-in.

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();

Mailchimp API v3.0 add email to list via NodeJS http

I'm using NodeJS to call the new MailChimp 3.0 API in order to add an email to a list. While I can get it working via POSTman, I'm having a hard time with Node's http:
var http = require('http');
var subscriber = JSON.stringify({
"email_address": "test#test.com",
"status": "subscribed",
"merge_fields": {
"FNAME": "Tester",
"LNAME": "Testerson"
}
});
var options = {
host: 'https://us11.api.mailchimp.com',
path: '/3.0/lists/<myListID>/members',
method: 'POST',
headers: {
'Authorization': 'randomUser myApiKey',
'Content-Type': 'application/json',
'Content-Length': subscriber.length
}
}
var hreq = http.request(options, function (hres) {
console.log('STATUS CODE: ' + hres.statusCode);
console.log('HEADERS: ' + JSON.stringify(hres.headers));
hres.setEncoding('utf8');
hres.on('data', function (chunk) {
console.log('\n\n===========CHUNK===============')
console.log(chunk);
res.send(chunk);
});
hres.on('end', function(res) {
console.log('\n\n=========RESPONSE END===============');
});
hres.on('error', function (e) {
console.log('ERROR: ' + e.message);
});
});
hreq.write(subscriber);
hreq.end();
Rather than getting even some sort of JSON error from Mailchimp, however, I'm getting HTML:
400 Bad Request
400 Bad Request
nginx
Is it clear at all what I"m doing wrong here? It seems pretty simple, yet nothing I've tried seems to work.
A few additional thoughts:
While http's options have an "auth" property, I'm using the headers instead to ensure the authorization is sent without the encoding (as mentioned here). Still, I've also tried with the "auth" property, and I get the same result.
I'm actually making this call from inside an ExpressJS API (my client calls the Express API, that calls the above code - I've edited all that out of this example for simplicity). That's why my variables are "hres" and "hreq", to distinguish them from the "res" and "req" in Express. Is there any reason that could be the issue?
As mentioned above, I am able to get successful results when using POSTman, so I at least know my host, path, list ID, and API key are correct.
It turns out this had a very simple solution: the "host" property of the options object needed to have only the domain name. IE, remove the "https://" protocol:
var options = {
host: 'us11.api.mailchimp.com',
path: '/3.0/lists/<myListID>/members',
method: 'POST',
headers: {
'Authorization': 'randomUser myApiKey',
'Content-Type': 'application/json',
'Content-Length': subscriber.length
}
}
Try this , its working fine for Me.
var request = require('request');
function mailchimpAddListCall(email, cb){
var subscriber = JSON.stringify({
"email_address": email,
"status": "subscribed"
});
request({
method: 'POST',
url: 'https://us13.api.mailchimp.com/3.0/lists/<Your list id>/members',
body: subscriber,
headers:
{
Authorization: 'apikey <your Mailchimp API key>',
'Content-Type': 'application/json'
}
},
function(error, response, body){
if(error) {
cb(err, null)
} else {
var bodyObj = JSON.parse(body);
console.log(bodyObj.status);
if(bodyObj.status === 400){
cb(bodyObj.detail, null);
}
var bodyObj = JSON.parse(body);
cb(null, bodyObj.email_address +" added to list.");
}
});
}
request is a node module, that you'll need to install into your package.json. npm install --save request
You can use the auth properties just fine with API v3, but if you're getting a 400, that's not the problem. The body of the 400 Error should provide more detailed information, but one thing that jumps out immediately: MailChimp doesn't allow fake or fake-looking emails to be added to lists (like test#test.com), so I'd try a real address and see if that works for you.

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.

Resources