Passport authenticate responding with HTTP 500 and does not call route methods after authentication succeeds - node.js

This is what my router method looks like.
router.get(/getData,
passport.authenticate("consumer-validation"),
getAccountData
);
I have a basic strategy defined here from passport-custom
const consumerValidationStrategy = new Strategy((req, done) => {
return done(null, { name: "John Doe" })
});
passport.use("consumer-validation", consumerValidationStrategy);
When I hit my /getData endpoint, I expect to see getAccountData being called but that doesn't happen.
I have also confirmed that the strategy is working by returning done("Error") which results in a 401 instead of 500.

Is this line exactly how you have it in your code: router.get(/getData, If so then I think it's missing quotation marks around the path value: router.get("/getData",.
Currently, you most probably have a syntax error because of the / used in the path.

Related

Express server returns 200 for routes that have not even been defined

I have been facing a weird thing for several days and I had no luck of solving that so far. The problem is I have a React.js frontend , Node Express.js backend and MongoDB, when I'm making requests to /api/users/update-pwd with proper parameters using axios, it doesn't update the password, but it returns 200. Then, I tried some routes such as /api/users/psosp. To my surprise, It also returned 200. I couldn't find the reason for that. Any helpful tip is highly appreciated.
Axios.post("/users/update-password",{
password: n_pwd
}).then(
res => {
alert("Password Updated")
}
).catch(err => {
console.log(err)
alert("An error occured")
})
Make sure that you don't have code like this in your backend.
router.post('/users/:userId',(req,res)=>{
// some operations
res.send();
});
router.post('users/update-password',(req,res)=>{
// some operations
res.send();
});
What above does is that it doesn't matter whatever you use in place of * /users/*/
the first route will be called by default
and also make sure that you did not use
app.use('*',(req,res)=>{
// some operations
res.send();
})
For any API call irrespective of the path the above code will be called.

Endpoint 'admin/authenticated' returns 200 success code no matter what and doesn't run code in controller

I have a NodeJS back-end API for my platform built on the framework SailsJS.
When the back-end endpoint is hit that checks if the user has been authenticated, I'd like to run some extra checks and maybe some console.log()s to debug an issue I'm having.
However, when I go to do this, it looks like I cannot because no matter what code I put at the controller tied to /admin/authenticated it just returns a 200 status code with no JSON data and any code I put in the controller function does not run! This is baffling me, do not understand how that could possibly happen.
In my routes.js folder I have:
'GET /admin/authenticated': 'AdminController.isAuthenticated',
Original code at the AdminController function isAuthenticated:
isAuthenticated: function (req, res) {
return res.json(req.user);
},
Some new code I've put in there that does NOTHING:
isAuthenticated: function (req, res) {
console.log("Running isAuthenticated.");
console.log(req.user);
return res.status(400).json({error: 'Sending back 400 error'});
},
Nothing is logged from the console.log()s and a 200 success code is sent back, not the 400 error I put in there.
I'm using the Passport authentication system, and think it must have something to do with that.
Can anyone help point me in the right direction? This is mystifying.

Async response - can't set headers after they are sent

I am new to Node.js programming. I am having a big trouble as I keep getting same error in the following code. I can not understand what is the problem there.
Can't set headers after they are sent.
var mongoose = require('mongoose');
module.exports = function(req, res) {
var User = require('../../Schema/User');
User.count({ $and: [{ "username": req.body.username }, { "password": req.body.password }] },
function(err, count) {
console.log(count);
res.json(count);
});
};
You are calling next() in your route code essentially turning your login snippet into middleware and passing it down. You are getting this error because in your login code you are outputting with res.json and then still calling the next step with next. l.
Your issue is just that headers must come before any output. Whether you write or pass the data on in your middleware is up to you as long as you are aware of subsequent possible headers/writes.
But you may want to reconsider your setup - in general auth middleware would be used to verify that a user is logged on - perhaps checking a session cookie. If the user is ok then you can fetch (if needed) user data based on the cookie info (i.e. the _id) or redirect the user to a login page.
What you have here is the login route which doesnt really need middleware. Simply check if user is valid and either set a session cookie or tell them it's a no go.
Passport makes things easier. Check out this post. The underlying principle is the same I outlined above, it just makes it easier to get going.

Sails.js custom route raises 500 forbidden for post requests

I have a user controller method like:
create: function( req, res ){
res.json({name:"Cool Name"});
}
But when use this
socket.post("/user/create", {
myName: "John Doe"}, function(r){ console.log(r) });
I get an error message "Forbidden" with status code 500. Its working fine when I make normal post request. Can you please throw some light on this.
You are posting to /user/create, which is the "shortcut" create URL. Shortcuts are accessed with the GET method (and should generally be turned off in production). To create a user via POST, use the /user URL:
socket.post("/user", {myName: "John Doe"}, function(r){ console.log(r) });

Exit after res.send() in Express.js

I have a fairly simple Express.js app with a login component that I'd like to exit early if login fails. I'm seeing indications that the app isn't doing that and I haven't found a definitive answer that indicates whether calling res.send() halts any further processing. Here's my code as it stands now:
client.login( username, password, function( auth, client ) {
if( !auth ) {
res.send( 401 );
}
// DO OTHER STUFF IF AUTH IS SUCCESSFUL
}
If I read the source code correctly, it should end the request (aborting further processing), but I'm new to node, so I'm not quite ready to trust what I think I'm reading. To boil it down, I guess I'm mostly looking for a definitive answer from a more trustworthy source that my own interpretation of unfamiliar source code. If send() doesn't abort processing, what's the right way to do that?
Of course express can not magically make your javascript function stop executing from somewhere else.
I don't like the next([error]) solution because I think errors should be only used for circumstances you usually don't expect (like an unreachable database or something). In this case, a simple wrong password would cause an error. It is a common convention to not use exceptions/errors for ordinary control flow.
I therefore recommend to place a return statement after the res.send call to make your function stop executing further.
client.login( username, password, function( auth, client ) {
if( !auth ) {
res.send( 401 );
return;
}
// DO OTHER STUFF REALLY ONLY IF AUTH IS SUCCESSFUL
}
If you are using express as your framework, you should call next() instead.
Each handler in express receives 3 parameters (unlinke 2 for basic http) which are req, res and next
next is a function that when called with no arguments will trigger the next handler in the middleware chain.
If next is called with an arguments, this argument will be interpreter as an error, regardless of the type of that argument.
Its signature is next([error]). When next is called with an error, then instead of calling the next handler in the middleware chain, it calls the error handler. You should handle the 401 response code in that error handler. See this for more info on error handling in Express
EDIT: As #Baptiste Costa commented, simply calling next() will not cease the current execution but it will call on the next middleware. It is good practice to use return next() instead to prevent Node from throwing errors further on (such as the can't set headers after they are sent - error). This includes the above suggestion of error throwing which is common:
return next(new Error([error]));
For your specific case you can just add the 'else' statement:
client.login( username, password, function( auth, client ) {
if( !auth ) {
res.send( 401 );
}else {
// DO OTHER STUFF IF AUTH IS SUCCESSFUL
}
}
Or, in general, you can use 'return':
return res.send( 401 );
in these cases , i tend to use a try...catch bloc .
client.login( username, password, function( auth, client ) {
try{
if(error1){
throw {status : 401 , message : 'error1'}
}
if(error2){
throw {status : 500 , message : 'error2'}
}
}catch(error){
res.status(error.status).json(error.message);
}
}
Simply do something like this to stop further execution.
function (request, response, next) {
var path = request.body.path;
if(path === undefined){
response.status(HttpStatus.BAD_REQUEST);
response.send('path is required!');
}
next(response)
};
You only need to do a return to end the flow:
return res.send( 401 );
That will send the 401 response back and won't proceed forward in the flow.
Why is no-one suggesting using an 'else' block?
if(!auth){
// Auth fail code
res.send 'Fail'
} else {
// Auth pass code
res.send 'Pass'
}
'next' is used when creating your own middleware for the "app.use(function(req, res, next));".
If you have set up a route like "app.get(route, function(req, res));" then the code in the function is where you can have the code you are specifying without needing to use 'next'.

Resources