I'm trying to use passport.js in my node.js app to authenticate a user with MongoDB. I never hit success.
In the post, I send "email": "[email protected]", "password": "test"
var passport = require('passport')
, LocalStrategy = require('passport-local').Strategy;
app.post('/login',
passport.authenticate('local', { successRedirect: '/',
failureRedirect: '/fail' })
);
passport.use(new LocalStrategy({
emailField: 'email',
passwordField: 'passw',
},
function (emailField, passwordField, done) {
process.nextTick(function () {
db.collection(users, function (error, collection) {
if (!error) {
collection.findOne({
'email': emailField,
'password': passwordField
}, function (err, user) {
if (err) {
return done(err);
}
if (!user) {
console.log('this email does not exist');
return done(null, false);
}
return done(null, user);
});
} else {
console.log(5, 'DB error');
}
});
});
}));
In MongoDB 'users' collection:
{
"_id": {
"$oid": "533b5283e4b09d8a1148b4c4"
},
"email": "[email protected]",
"password": "test"
}
Maybe I am not connecting to the database right, I'm not sure.
Also, when I log all throughout the function, I don't get ANY logs. I simply get
POST /login 302 7ms - 39b
GET /fail 404 3ms
Any suggestions would be greatly appreciated. I think I may be missing something but I'm not sure exactly how to structure this. In the other function where I'm writing to the database I have to use:
var uristring =
process.env.MONGOLAB_URI ||
process.env.MONGOHQ_URL ||
'mongodb://<myurlhere>';
mongo.connect(uristring, function (err, db) {
Here is the updated code
requiring these:
, passport = require('passport')
, LocalStrategy = require('passport-local').Strategy;
using these:
// all environments
app.set('port', process.env.PORT || 3000);
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.json());
app.use(express.urlencoded());
app.use(express.methodOverride());
app.use(express.cookieParser());
app.use(express.session({ secret: 'keyboard cat'}));
app.use(logfmt.requestLogger());
app.use(express.static(path.join(__dirname, 'public')));
app.use(passport.initialize());
app.use(passport.session());
app.use(app.router);
// User authentication passport
passport.use(new LocalStrategy(
{
usernameField: 'email',
passwordField: 'passw',
},
function (userId, password, done) {
// removed process.nextTick
console.log('Hey! no more 400 error!');
db.collection(users, function (error, collection) {
if (!error) {
collection.findOne({
'email': userId,
'password': password
}, function (err, user) {
if (err) {
return done(err);
}
if (!user) {
console.log('this email does not exist');
return done(null, false);
}
return done(null, user);
});
} else {
console.log(5, 'DB error');
}
});
}
));
passport.serializeUser(function(user, done) {
done(null, user);
});
passport.deserializeUser(function(user, done) {
done(null, user);
});
app.post('/login', passport.authenticate('local'), function(req, res) {
console.log('SUCCESS WOOOO');
// If this function gets called, authentication was successful.
// `req.user` contains the authenticated user.
//res.redirect('/users/' + req.user.username);
});
This code always gives me POST /login 400 10ms
when posting to /login. All my other routes work fine.
1) The dreaded HTTP 400 error
Passport throws an HTTP 400 error when the username and/or password are not set.
See the source around line 75 where Strategy.prototype.authenticate
throws a 'missing credentials' error.
2) Diagnosing the cause
In your code, you have the block:
passport.use(new LocalStrategy({
emailField: 'email',
passwordField: 'passw',
},
But emailField
isn't recognized by passport. Back in the source code, we see that passport is looking for:
this._usernameField = options.usernameField || 'username';
this._passwordField = options.passwordField || 'password';
This is why the HTTP 400 is being thrown in this specific situation.
4) Fixing the problem
I've edited your original code to what I believe will work (better) than the original. I took some liberty when editing to remove the process.nextTick
and renamed a few things. I hope you are a forgiving person. :)
passport.use(new LocalStrategy(
{
usernameField: 'email',
passwordField: 'passw',
},
function (userId, password, done) {
// removed process.nextTick
console.log('Hey! no more 400 error!');
db.collection(users, function (error, collection) {
if (!error) {
collection.findOne({
'email': userId,
'password': password
}, function (err, user) {
if (err) {
return done(err);
}
if (!user) {
console.log('this email does not exist');
return done(null, false);
}
return done(null, user);
});
} else {
console.log(5, 'DB error');
}
});
}
));
5) Some closing notes:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With