Need to check if user exists and return true or false

3,149 views
Skip to first unread message

Enrique Shadah

unread,
Dec 9, 2014, 11:17:47 PM12/9/14
to node-mong...@googlegroups.com
Hi,
I have spent many hours trying setup a helper function that allows passport-local to verify if a user with username/password exists in mongo, returning true/false.  My problem is that the db.collection().findOne() statements don't seem to be returning anything.  Here's the code:

functions.checkPassword = function (username, password) {

db
.collection('myColl', function(err,collection) {
collection.findOne({username:username,password:password}, function(err,user){
if (err) {
console.log('This is the error from MongoDB: '+err);
} else {
console.log('returned the valid user: '+user.username);
for (var i in user){
console.log(i,user[i]);
}
if (user.username === username) {
return true; //this is not returning back to the statement that called the helper function
} else {
return false; //this is not returning back to the statement that called the helper function
}
}
});
});
// return true; --> if I uncomment this return, then the function works (obviously).
}; 

Any thoughts welcomed.

Jason Crawford

unread,
Dec 10, 2014, 12:35:47 AM12/10/14
to node-mong...@googlegroups.com
You don't seem to understand how callbacks work. You can't return true/false immediately from your checkPassword function, because the answer isn't known immediately. It isn't known until the inner callback is invoked, where you have your real returns.

What you need is to pass a callback in as an argument to checkPassword, alongside username and password. Often this callback is called 'done', and it's invoked with the return value, when that value is available. If you look at passport-local, that's how it works.

Incidentally, you should never verify usernames and passwords by looking them up in a database directly like this! Never store passwords in the database. You need to use a password hashing module like bcrypt to safely store password hashes (not raw passwords) and then compare them to the submitted password at login time. Google it and you should find relevant info.

Hope that helps,
Jason

--
Blog: http://blog.jasoncrawford.org  |  Twitter: @jasoncrawford



--
You received this message because you are subscribed to the Google Groups "node-mongodb-native" group.
To unsubscribe from this group and stop receiving emails from it, send an email to node-mongodb-na...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Enrique Shadah

unread,
Dec 10, 2014, 12:58:47 AM12/10/14
to node-mong...@googlegroups.com
Tx!! Will try tomorrow and let u know if it worked! Still learning...:)

Founder
You received this message because you are subscribed to a topic in the Google Groups "node-mongodb-native" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/node-mongodb-native/EcyRAPKrEVY/unsubscribe.
To unsubscribe from this group and all its topics, send an email to node-mongodb-na...@googlegroups.com.

Enrique Shadah

unread,
Dec 10, 2014, 7:31:25 PM12/10/14
to node-mong...@googlegroups.com
Jason,

Stupid question: is "done" a pre-defined callback function in node or do I need to define it var done = function (){};?  
To unsubscribe from this group and stop receiving emails from it, send an email to node-mongodb-native+unsub...@googlegroups.com.

Jason Crawford

unread,
Dec 10, 2014, 10:46:11 PM12/10/14
to node-mong...@googlegroups.com
Neither. The 'done' function needs to be an *argument* to your checkPassword function. See the first example here: https://github.com/jaredhanson/passport-local

To unsubscribe from this group and stop receiving emails from it, send an email to node-mongodb-na...@googlegroups.com.

Enrique Shadah

unread,
Dec 10, 2014, 11:30:22 PM12/10/14
to node-mong...@googlegroups.com
I see. But still don't understand what is inside done().  I am doing some reading on node fundamentals to see if it's like an event emitter/listener.  I am about to grasp the concept, but i am not there yet!! 
Jason,

To unsubscribe from this group and stop receiving emails from it, send an email to node-mongodb-native+unsubscribe...@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

Enrique Shadah

unread,
Dec 14, 2014, 11:21:04 PM12/14/14
to node-mong...@googlegroups.com
Hi Jason,

I have tried in vane to get the simple true/false to verify if user exists using mongo and passport in an express/nodejs app.  I tried using callbacks as you mentioned, but don't seem to be able to get functions called in sequence.  Should I use a flow-control strategy? 

This is my auth.js code (from which I call the users.checkPassword method):

var passport = require('passport');
var LocalStrategy = require('passport-local').Strategy;
var users = require('./users');

module.exports = function () {
var user ={};

passport.use(new LocalStrategy ({
        passReqToCallback : true
},
function(req, username, password, done){
console.log('im inside local strategy');

// - here is my problem...
var validateUser = users.checkPassword(username, password);
console.log('this is validate user: '+validateUser);
// -- this block of code should validate the existence of the user in Mongodb.

if (validateUser) {
var user = {username:username};
return done(null, user);
} else {
return done(null, false);
}
}));

passport.serializeUser(function(user, done){
console.log('serializing '+user.username);
if(user){
done(null, user.username);
});

passport.deserializeUser(function(username, done){
console.log('deserializing ' + username);
//find user with username as key -- this is a simple example
user = {username:username}; // founder user
if (user) {
done(null, user);
} else {
done(null, false);
}
});

};


This is my users.checkPassword function (which is linked to mongo (via native driver)):

functions.checkPassword = function (username, password) {
var x = ['yikes'];
db.collection('monetize_u', function(err,collection) {
var query = {username:username,password:password};
collection.findOne(query,function (err, user){
if (user) {
if (user.username === username) {
console.log('user found');
x.push(user);
return x;
} else {
console.log('user not found');
return false;
}
} else {
console.log('This is the error from MongoDB: '+err);
}
});
});
console.log(x[0]);
return true;//this is a dummy value to make sure that the other code works.  Although I successfully load the user, don't know how to respond back with "true".
};

Jason Crawford

unread,
Dec 14, 2014, 11:31:14 PM12/14/14
to node-mong...@googlegroups.com
You need to add the 'done' function as an *argument* to checkPassword. Then when you have the answer, you call done(user). You do not return anything from checkPassword itself—you can't, because you don't have the result yet to return.

If that doesn't make sense, I recommend working through a tutorial on how callbacks work in Node. Your confusion here suggests to me that you may need a better grounding in the fundamentals before you can get code like this to work.

BTW, if you have more questions, it might make sense to post them on the Passport list rather than here on the Mongo list… this isn't really a Mongo question.

Hope that helps,
Jason

--
Blog: http://blog.jasoncrawford.org  |  Twitter: @jasoncrawford


To unsubscribe from this group and stop receiving emails from it, send an email to node-mongodb-na...@googlegroups.com.

Enrique Shadah

unread,
Dec 14, 2014, 11:47:10 PM12/14/14
to node-mong...@googlegroups.com
Jason,
Got it.  Will do.  The only portion that is related to Mongo is that db.collection().findOne() returns a user, but I can't assign that user to an array or object outside the db..() functions. I am reading books on fundamental, etc. so thanks for taking the time to respond.  I am very grateful.
Thanks again. I will post hopefully once I succeed.


You received this message because you are subscribed to a topic in the Google Groups "node-mongodb-native" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/node-mongodb-native/EcyRAPKrEVY/unsubscribe.
To unsubscribe from this group and all its topics, send an email to node-mongodb-na...@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.
Reply all
Reply to author
Forward
0 new messages