I am trying to make a WebAPI call from server script and i am getting authentication error:
This is how my server.js looks like:
var app = require('http').createServer()
, io = require('socket.io').listen(app)
, fs = require('fs')
, moment = require('moment')
, request = require('request'); //https://github.com/mikeal/request
app.listen(8000, function () {
console.log('server started');
doSomethingOnServerStart();
});
function doSomethingOnServerStart()
{
console.log('Getting something from server');
request.get({
url: 'http://localhost:63213/Api/MyAPI/GetSomething',
},
function (error, response, body) {
console.log(response.statusCode);
if (response.statusCode == 200) {
console.log('data received from server');
} else {
console.log('error: ' + response.statusCode);
console.log(body);
}
});
}
I am using Mikeal's Request library to make the WebAPI call. In the HTTP Authentication section (https://github.com/mikeal/request#http-authentication), it says pass username and password as "hash" but does not say how do i generate that hash.
I am kind of stuck and dont know how to proceed.
To address your initial question, judging from the documentation it looks like you need to make an additional chained function call:
request.get('http://some.server.com/').auth('username', 'password', false);
or like this
request.get('http://some.server.com/', {
'auth': {
'user': 'username',
'pass': 'password',
'sendImmediately': false
}
});
In the second case it mentions having to have auth as a hash (as it is above). It doesn't appear you're sending a username or password anywhere in your code...
Related
I am experimenting with the softlayer-client api wrapper in my Node Express application. My goal is to update the VPN password of a User_Customer by calling the updateVpnPassword method on a specific user.
I can construct a call to achieve a VPN password update using request, but I'm not sure it's the best way to achieve the desired result.
Can the softlayer-client module be used to make an similar call to this:
function updateVpnPassword(req, res, next) {
// Construct URL to update VPN
myURL = 'https://' + <userIDAdmin> + ':' + <apiKeyAdmin> + '#api.softlayer.com/rest/v3/SoftLayer_User_Customer/' + <softLayerID> + '/updateVpnPassword/' + <newPassword> + '.json';
request.get({url: myURL}, function (error, response, body) {
console.log('error:', error);
console.log('statusCode:', response && response.statusCode);
console.log('body:', body);
});
next();
}
My initial attempts have been to try variations on this:
function updateVpnPassword(req, res, next) {
// Assuming var client = new SoftLayer();
client
.auth(<userIDAdmin>, <apiKeyAdmin>)
.path('User_Customer', <softLayerID>,'updateVpnPassword')
.parameters(<newPassword>)
.put(function(err,result){
console.log(result);
if (err) {
next(err); // Pass errors to Express.
}
else {
// update successful
}
});
next();
}
But the console log gives an error response like
{ message: { error: 'Internal Error', code: 'SoftLayer_Exception_Public' } }.
I expect a TRUE or FALSE response, to indicate the whether the update is successful.
A similar python client can be found here but I require an implementation in JS.
I'm not familiar with nodejs but I installed the package softlayer-node and run your second code and it worked.
I also created the following script and I got TRUE
var username = 'set me';
var apikey = 'set me';
var userId = 1111111;
var SoftLayer = require('softlayer-node');
var client = new SoftLayer();
client
.auth(username, apikey)
.path('User_Custome', userId, 'updateVpnPassword')
.parameters('P#ssword123')
.put()
.then(function(result) {
console.log(result);
}, function(error) {
console.log(error);
});
node command:
$ node updateVpnPassword.js
true
Did you tried by sending that request using curl or any other REST client like postman?
If you get the same error then I recommend you submit a ticket and provide information like the id of users you are trying to update the vpn password and the user with which you are sending the request.
I have to do request from node to Yii2 api. It doesn't throw any errors, but doesn't return anything either. When I do request to Yii2 api method directly in browser, value is returned. Here is my request in route in node:
router.get('', function (req, res) {
var parameter = 20;
request({
url: 'http://**.**.**.***:8000/web/index.php?r=api/get-value',
parameter: parameter,
method: 'GET'
}, function(error, response, body) {
if(error || response.statusCode != 200)
throw error;
res.send(body);
});
});
module.exports = router;
And here is method/endpoint in Yii2 controllers/apiController.php:
public function actionGetValue($inverterId) {
return $inverterId * 2;
}
Any suggestions what could be wrong/missing?
You can use the following
var http = require('http');
var client = http.createClient(8000, 'localhost');
var request = client.request('GET', '/web/index.php?r=api/get-value');
request.write("stuff");
request.end();
request.on("response", function (response) {
// handle the response
});
Resource Link:
Http request with node?
Sending http request in node.js
or Another full example:
Get requests
Now we’ll set up a super simple test to make sure it’s working. If it’s not still running, run your simple Node server so that it’s listening on http://localhost:8000. In a separate file in the same directory as your http-request.js where your new module lives, add a file called test-http.js with the following contents:
// test-http.js
'use strict';
const
request = require('./http-request'),
config = {
method: 'GET',
hostname: 'localhost',
path: '/',
port: 8000
};
request(config).then(res => {
console.log('success');
console.log(res);
}, err => {
console.log('error');
console.log(err);
});
This will import our module, run a request according to the configured options, and console log either the response, or an error if one is thrown. You can run that file by navigating to its directory in the command line, and typing the following:
$ node test-http.js
You should see the following response:
success
{ data: 'Cake, and grief counseling, will be available at the conclusion of the test.' }
Resource Link:
https://webcake.co/sending-http-requests-from-a-node-application/
Okay, shame on me, I did not check, what's going on in public function beforeAction($action) in apiController.php - since request to endpoint getValue() is done from the "outside", it falls under a condition, that does not allow further actions and returns false - that's why response wasn't changing no matter what was done/set in getValue().
So I want to use this: (taken from their API site -> node.js documentation)
https://github.com/blockchain/api-v1-client-node
Recieving payments:
https://github.com/blockchain/api-v1-client-node/blob/master/docs/Receive.md
var blockchain = require('blockchain.info');
var identifier = 'myidentifier';
var password = 'mypassword';
var myWallet = new blockchain.MyWallet(identifier, password);
var myBTCadress = '14Q3ufL1BUHtWskBKtsshVDATRY65TaJMB';
Ok, so the recieving part:
var receive = new blockchain.Receive( [confirmations: 1], ? ); // What do I need to put here?
Documentation says:
callbackURL: the url to which the callback should be sent (string)
I don't understand what URL it should go to?!
The callback URL should be the one that redirects back to your site. So setup a callback url with blockchain like...
https://www.yoursite.com/callback/blockchain
Assuming you are using something like express in your app make a route like so.
app.get('/callback/blockchain', function (req, res) {
// Stuff here
});
you will prob need to include
var https = require('https');
That way then you can set up your logic inside for example...
// Stuff here
var options = {
host : 'api.blockchain.info',
path : '/some/path/',
port : 443,
method : 'GET'
}
var request = https.request(options, function(response){
var body = ""
response.on('data', function(data) {
body += data;
});
response.on('end', function() {
res.send(JSON.parse(body));
});
});
request.on('error', function(e) {
console.log('Problem with request: ' + e.message);
});
request.end();
That will for example output you request in json on whatever page you have your app.get('whateverurl') set to.
I need to connect to a web page and return the status code of the page, which I've been able to achieve using http.request however the pages I need to request can take a long time, sometimes several minutes, so I'm always getting a socket hang up error.
I'm using the following code so far:
var reqPage = function(urlString, cb) {
// Resolve the URL
var path = url.parse(urlString);
var req = http.request({
host: path.hostname,
path: path.pathname,
port: 80,
method: 'GET'
});
req.on('end', function() {
cb.call(this, res);
});
req.on('error', function(e) {
winston.error(e.message);
});
};
What do I need to do to ensure that my application still attempts to connect to the page even if it's going to take a few minutes?
Use the request module and set the timeout option to an appropriate value (in milliseconds)
var request = require('request')
var url = 'http://www.google.com' // input your url here
// use a timeout value of 10 seconds
var timeoutInMilliseconds = 10*1000
var opts = {
url: url,
timeout: timeoutInMilliseconds
}
request(opts, function (err, res, body) {
if (err) {
console.dir(err)
return
}
var statusCode = res.statusCode
console.log('status code: ' + statusCode)
})
Add this if you don't want to use a higher level http client like request or superagent , then add this...
req.on("connection", function(socket){
socket.setTimeout((1000*60*5)); //5 mins
});
Here is the thing :
I have a client which sends data to a server. This server has to contact an external A.P.I. and send back its response to the client. I just can't figure out how and where I can contact the external A.P.I once the server has got the client data.
I route client data like this :
app.post('/getAutoComplete', routes.read);
routes.read retrieves the data within req.body. With my nodejs version (without express framework), I then request the api this way :
var http = require('http'), options = {
host : "192.168.1.38",
port : 8080,
path : "/myURL",
method : 'POST'
};
var webservice_data = "";
var webservice_request = http.request(options, function(webservice_response)
{
webservice_response.on('error', function(e){ console.log(e.message); });
webservice_response.on('data', function(chunk){ webservice_data += chunk;});
webservice_response.on('end', function(){res.send(webservice_data);});
});
webservice_request.write(req.body);
webservice_request.end();
The problem is that i'd like to use native expressJS method like app.post but I don't know how because :
Express (app) object is not available here (declared in app.js but not in the route file)
I don't know how to send POST data with app.post
Any suggestion ?
app.post('/getAutoComplete', routes.read);
// assuming routes.read lookes something like this
routes.read = function read(req, res) {
var http = require('http'), options = {
host : "192.168.1.38",
port : 8080,
path : "/myURL",
method : 'POST'
};
var webservice_data = "";
var webservice_request = http.request(options, function(webservice_response)
{
webservice_response.on('error', function(e){ console.log(e.message); });
webservice_response.on('data', function(chunk){ webservice_data += chunk;});
webservice_response.on('end', function(){res.send(webservice_data);});
});
webservice_request.write(req.body);
webservice_request.end();
};
Also check out https://github.com/mikeal/request It's the de-facto module for doing web requests in node.
routes.read is a function. You can call it with extra parameters, so for example
app.post('/getAutoComplete', function(req,res) {
var q = req.query.q; // or whatever data you need
routes.read(q, function(err, response) {
if (err) throw err;
return res.json(response);
});
});
Now make the routes.read function use the first parameter as the query and when it's gathered the response from the remote API, call the second parameter with any error as the first parameter and the response as the second one.
Update This answer has already been picked as an answer, but it'd be more helpful if I showed an example of routes.read, too:
routes.read = function(q, cb) {
// pretend we calculate the result
var result = q * 10;
if (result > 100) {
// call the callback with error set
return cb("q value too high");
}
// all is well, use setTimeout to demonstrate
// an asynchronous return
setTimeout(function() { cb(null, result) }, 2000);
};