Async Processing for Node.js POST Request Response - node.js

I'm relatively new to Node.js and I'm creating a server that will accept a POST request from a mobile app whose body contains a credential that will then be verified via a GET to another server. If the GET response validates the credential, then the UID is extracted and a call is made to the firebase admin SDK to create a custom token. Here is a snippet of the code and two functions that are called to (a) validate the credential and (b) generate the custom token.
//Listen for app to POST Credential
app.post('/', function(request, response) {
console.log('Request Body: ',request.body);
var Credential = request.body;
//Validate Credential
validateCredential(Credential)
//Get Authorization Token
getToken(userID)
//Return Token for POST Response
response.set('Content-Type','Text');
response.end(firebaseAuthToken);
});
//Create listener for POST function
app.listen(port, function() {
console.log('AuthServer is running and listening on port '+port);
});
//Function to Validate Credential
async function validateCredential(crdntl) {
//Call Service to validate Credential received
axios({
method: 'get',
url: 'https://.....',
})
.then(function(response) {
...check credential validation data
})
.catch(function (error) {
console.log('ERROR: Unable to Validate Credential');
//Unable to create Validate Credential so return error message for POST response
return ('ERROR1');
});
}
async function getToken(uid) {
admin.auth().createCustomToken(uid)
.then(function(customToken) {
var AuthToken = customToken;
var decoded = jwt.decode(AuthToken);
console.log('Decoded Token: '+'\n',decoded);
//Return Authorization Token for POST response
return (AuthToken);
})
.catch(function(error) {
console.log('ERROR: Unable to Create Custom Token', error);
//Unable to create Token so return error message for POST response
return ('ERROR2');
});
}
}
I need the result of the validateCredential function to be returned and its result passed to the getToken function and its result returned so that the POST response can be sent. I know these function are async and I can chain them with callbacks or promises.
The real issue is how to make the POST response wait for a callback from the getToken function as the ultimate goal is to pass the custom token back to the mobile app in the body of the POST response.
Any help would be appreciated.

Your validateCredential and getToken functions are already async which in turn returns promise, To wait in POST function for these functions to send response, You have to make POST function async and then use await keyword while calling those 2 functions, when you use await function execution waits until function response which is Promise resolves, Here is sample code.
//Listen for app to POST Credential
app.post('/', async function(request, response) {
console.log('Request Body: ',request.body);
var Credential = request.body;
//Validate Credential
var userId = await validateCredential(Credential) //Waits until userId comes
//Get Authorization Token
var firebaseAuthToken = await getToken(userID) //waits until Token comes
//Return Token for POST Response
response.set('Content-Type','Text');
response.end(firebaseAuthToken);
});

Related

How to obtain the token from the current user with jwt/express/node

I have a controller that receives an user that is trying to login via form. When all validations are checked, the user will be logged in and a token will be created in the following way:
const token = jwt.sign({userId: user._id}, config.secret ,{expiresIn: '24h'})
res.json({success: true, message: 'Sesión iniciada', token: token, user: {email: user.email}})
However, how do I access this token from another controller? I've seen that a good approach would be to create a middleware that intercepts such token, but I don't really know how to accomplish this.
I'd be happy only knowing how to get the token tho. I'm kinda new and I'm taking very small steps.
You should setup your client requests to send such token as #Vahid said.
Here's an example with axios
const instance = axios.create({
baseURL: 'https://some-domain.com/api',
// From the docs:
// `transformRequest` allows changes to the request data before it is sent to the server
// This is only applicable for request methods 'PUT', 'POST', 'PATCH' and 'DELETE'
// The last function in the array must return a string or an instance of Buffer, ArrayBuffer,
// FormData or Stream
// You may modify the headers object.
transformRequest: [function (data, headers) {
headers['Authorization'] = localStorage.getItem('jwt')
return data;
}],
})
export default instance
In case you also need GET request you can add:
export setAuthToken = (token) => {
instance.defaults.headers.common['Authorization'] = token;
}
Although you'll need to call it every time your JWT is renewed.
After that, you could catch it using the Middlewares to decode the token from the headers
app.use((req, res, next) => {
const authToken = req.headers['Authorization']
if(authToken) {
try {
const decoded = jwt.verify(authToken, config.secret)
req.user = decoded.userId
// Hopefully
// req.user = getUserById(decoded.userId)
next()
} catch(e) {
// Handle Errors or renewals
req.user = null
// You could either next() to continue or use 'res' to respond something
}
} else {
// Throw 403 if should be authorized
res.sendStatus(403)
}
})
This way you should be able to access req.user on any route defined after your middleware.
Eg:
app.post('/me', (req, res) => {
res.send(req.user)
})
Note that this is just one example of a global middleware. In other cases, you should be able to create custom middlewares based on which routes you want to protect or with which amount of permissions.

Node & Express Endpoint always returns 200

I am having issues with a block of code in my node.js API. I have a simple JWT authentication API that is working as expected in terms of logging in and authentication. Howvever I cannot get express to return a response status other then 200.
If I enter an invalid username or password for the login end point, the response I receive is an empty 200 response, despite the fact the below code executes the catch block, and I return a response of 500 with my error. from the post method. This is getting lost somewhere, and converted to the empty 200 response. On succesfull login the return res.status(200).json.... code returns the correct response.
I have the same issue on all endpoints, all error responses are return as an empty 200 response.
Could any one advise.
app.post('/user/login', async (req, res) => {
const email = req.body.user.email;
const password = req.body.user.password;
try {
const authServiceInstance = new AuthService();
const { user, token } = await authServiceInstance.Login(email, password);
return res.status(200).json({ user, token }).end();
} catch(e) {
console.log('Error in login: ', e);
return res.json(e).status(500).end();
}
})

Swift & Firebase Functions: HTTPS authenticate the user

i have some https Cloud Functions which I want to secure by authorizing the user sending the request.
My function looks like this:
exports.authTester = functions.https.onRequest((req, res) => {
const tokenID = req.get('Authorization').split('Bearer ')[1];
return admin.auth().verifyIDToken(tokenID)
.then((decoded) => res.status(200).send(decoded))
.catch((err) => res.status(401).send(err));
console.log(decoded);
});
Within my App I'm calling the function via Alamofire:
Alamofire.request(url, method: .get).responseString { (response) in
if let dta = response.response?.statusCode{
print(response)
}
}
However, my console logs that the function crashes due to the hint:
"Cannot read property 'split' of undefined
at exports.authTester.functions.https.onRequest (...)"
How can I solve this issue?
Thank´s!
You're getting this error because you aren't invoking your cloud function with the proper command that is to passing the token in the HTTP header.
You'd be doing something like:
let token: String = "Bearer" + ...
let header = ["Authorization": token]
// then you pass your header into Alamofire request
Here is a link to on how to do a POST Request from Alamofire?,
a link from Alamofire Docs

nodejs restclient authentication and fetch session data

I am new nodejs, Currently I am using rest-client to fetch the data from proxy service. Initially By using POST method of rest Client I am able to login my proxy and I am getting a success response.
after login Immediately I am calling 'get'(proxy/user/me) method for fetching the session data, then I am facing login failed message, How can I will check each time before fetching any other data using nodejs.
//Example POST method invocation for Login
//after Login get method invocation
var Client = require('node-rest-client').Client;
var client = new Client();
var fs = require('fs');
var email = "raj#ioynx.io";
var proxy = "http://google.com";
var password = "abcd";
// set content-type header and data as json in args parameter
var args = {
data: JSON.stringify({ username: email, password: password }),
headers: { "Content-Type": "application/json" }
};
client.post(proxy+"login", args, function (data, response) {
//Sucessfully Login message Dis[play with status Code 200
console.log(response.statusCode);
if (parseInt(response.statusCode) === 200) {
//after success I am trying to fetch session Data, 'get' mehode will always shows ,there is no login.
client.get(proxy+"user/me", function (sessionData, sessionResponse) {
//The second URL for fetching session data always shows { message: "not Login message" }
console.log(sessionData, 'Dubt', sessionResponse.statusCode);
});
}
});
You will need to wrap each method with some sort of authentication checker. Something like this-
function wrapAuthentication(fn) {
return function() {
// Check authentication
if(authenticated) {
fn.apply(fn, arguments);
}
}
}
function updateUserData() {
// Do stuff
}
client.post(proxy+"login", args, wrapAuthentication(updateUserData));
You're rest framework may support something like this already.

How to send the OAuth request in Node

I want to access the WS REST API in node.js. I have the oauth_consumer_key and the oauth_token and the API end point. The oauth_signature_method is HMAC-SHA1.
How to send the OAuth request in Node?
Is there a module/library to generate the request headers? What I expect is a function like:
var httprequest = createRequest(url, method, consumer_key, token);
UPDATE 10/14/2012. Adding the solution.
I'm using the code below.
var OAuth = require('oauth').OAuth;
consumer = new OAuth('http://term.ie/oauth/example/request_token.php',
'http://term.ie/oauth/example/access_token.php',
'key', 'secret', '1.0',
null, 'HMAC-SHA1');
// Get the request token
consumer.getOAuthRequestToken(function(err, oauth_token, oauth_token_secret, results ){
console.log('==>Get the request token');
console.log(arguments);
});
// Get the authorized access_token with the un-authorized one.
consumer.getOAuthAccessToken('requestkey', 'requestsecret', function (err, oauth_token, oauth_token_secret, results){
console.log('==>Get the access token');
console.log(arguments);
});
// Access the protected resource with access token
var url='http://term.ie/oauth/example/echo_api.php?method=foo&bar=baz';
consumer.get(url,'accesskey', 'accesssecret', function (err, data, response){
console.log('==>Access the protected resource with access token');
console.log(err);
console.log(data);
});
We use https://github.com/ciaranj/node-oauth
This is more of a complete node twitter package that seems streamlined and useful.
https://npmjs.org/package/twitter

Resources