I want to consume a REST api that needs a username/password authentication in node.js. The code that consumes the api is as follows:
var request = require('request');
var url = 'http://localhost:3000/api/v1/login/'
request.get(url,{'auth': {'user': 'test35','pass': 'mypassword','sendImmediately': false}},function(err, httpResponse, body) {
if (err) {
return console.error('post failed:', err);
}
console.log('Post successful! Server responded with:', body);
});
With the above code, the error I get is:
{
"status": "error",
"message": "API endpoint does not exist"
}
The api is written in meteor restivus and you can see it in the following question's answer here
In the API, when I remove the api's authRequired: true, i.e, remove
{
routeOptions: {
authRequired: true
}
}
and in the code that consumes the API above, change url from
to:
and run "node accessRESTapi.js", I am able to consume the REST api! What I am not able to do correctly is the authentication when "authRequired: true" is set as per above! Please help
EDIT: Updated based on info from comments
The style of request is quite different between logging in to get a token and the subsequent requests:
The docs specify that login actions must be done with a POST
request to /api/login/
with a body that contains username
or email
and password
as url-encoded params
var request = require('request');
var url = 'http://localhost:3000/api/v1/login/'
var user = 'test35';
var pass = 'mypassword';
// Save these for future requests
var userId;
var authToken;
// Use POST instead of GET
request.post(
{
uri: url,
// I'm using form because it matches the urlEncoding behaviour expected by `restivus`
form: { username: user, password: pass }
},
function(err, httpResponse, body) {
if (err) {
return console.error('post failed:', err);
}
var json = JSON.parse(body);
authToken = json.data.authToken;
userId = json.data.userId;
console.log('Post successful! Server responded with:', body);
}
);
Now you need to set the correct headers with the previously saved userId
and authToken
According to the docs, that means X-User-Id
and X-Auth-Token
headers on all subsequent requests
var request = require('request');
var url = 'http://localhost:3000/api/v1/articles/'
request.get({
uri: url,
headers: {
'X-User-Id': userId,
'X-Auth-Token': authToken
}
}, function(err, httpResponse, body) {
if (err) {
return console.error('get failed:', err);
}
console.log('Get successful! Server responded with:', body);
});
We want to make sure we get the authToken
before making any further requests.
This means making the second request in the callback of the first function like so:
var request = require('request');
var url = 'http://localhost:3000/api/v1/login/';
var user = 'test35';
var pass = 'mypassword';
// Save these for future requests
var userId;
var authToken;
// Use POST instead of GET
request.post(
{
uri: url,
// I'm using form because it matches the urlEncoding behaviour expected by `restivus`
form: { username: user, password: pass }
},
function(err, httpResponse, body) {
if (err) {
return console.error('post failed:', err);
}
var json = JSON.parse(body);
authToken = json.data.authToken;
userId = json.data.userId;
console.log('Post successful! Server responded with:', body);
// And now we make the second request
// Welcome to callback hell
var articlesUrl = 'http://localhost:3000/api/v1/articles/';
request.get({
uri: articlesUrl,
headers: {
'X-User-Id': userId,
'X-Auth-Token': authToken
}
}, function(err, httpResponse, body) {
if (err) {
return console.error('post failed:', err);
}
console.log('Get successful! Server responded with:', body);
});
}
);