passport js check for error in req - javascript

I am logging in a user with passport local:
// route to log in
app.post('/login', passport.authenticate('local-login'), function(req, res) {
res.send(req.user);
});
This will only work in the case of success, i.e. when req.user is defined. How do I check for an error in the request? Essentially I want to take the error that was pulled from my passport authentication code in the done() call and send that back to the client to display the proper error message:
passport.use('local-login', new LocalStrategy({
username : 'email',
password : 'password',
passReqToCallback : true
},
function(req, email, password, done) {
console.log('logging in user: ' + email);
// find a user whose email is the same as the forms email
// we are checking to see if the user trying to login already exists
Landlord.findOne({ 'local.email' : email }, function(err, user) {
if (err) return done(err);
if (!user) return done(null, false, { message: 'Incorrect username.' });
if (!user.validPassword(password)) {
console.log('wrong pw');
return done(null, false, { message: 'Incorrect password.' });
}
return done(null, user);
});
}));

Related

Passport.js BasicStratagy retuns unauthorized to logged in user in a Rest API

I am working on a Rest API with Passport.js. after I log in and use a secured endpoint, I get "unauthorized" as a response. what is more confusing is that after I call the log in function, I get a valid user. here is Passport config:
passport.use(new BasicStrategy({
usernameField: 'email',
passwordField: 'password'
},
function(email, password, done) {
console.log("Email: ", email)
console.log("password: ", password)
User.findOne({ email: email }, function (err, user) {
if (err) { return done(err) }
if (!user) { return done(null, false) }
if (!bcrypt.compare(password, user.password)) { return done(null, false) }
return done(null, user);
})
}
))
I used the following middle ware code to secure it: passport.authenticate('basic', {session: false})

PassportJS: serializeUser() Can't set headers after they are sent

I am simply trying to serialise the user in passportjs following the "normal" flow. However I keep getting the following error:
Error: Can't set headers after they are sent.
I don't understand where I could send the res since I am just using the middleware to send it. Here is how I call the authentication route:
routes.post('/signup', function(req, res, next) {
passport.authenticate('local-signup-sme', {
successRedirect : req.get('origin') + '/dashboard', // redirect to the secure profile section
failureRedirect : req.get('origin') + '/signupSME', // redirect back to the signup page if there is an error
failureFlash : true,
successFlash : 'User created !'
})(req, res, next)
});
and here is my local-signup-sme, i only call done() and I only call it once, or in a callback, I have checked if there was any if without an else but I can't find any...
What am I doing wrong ?
// used to serialize the user for the session
passport.serializeUser(function(user, done) {
done(null, user.id);
});
passport.use('local-signup-sme', new LocalStrategy({
// by default, local strategy uses username and password, we will override with email
usernameField : 'email',
passwordField : 'password',
passReqToCallback : true // allows us to pass in the req from our route (lets us check if a user is logged in or not)
},
function(req, _email, _password, done) {
if (typeof _password === 'undefined' ){
return done(null, false, {message: 'Password field is missing'})
} else if( typeof _email === 'undefined'){
return done(null, false, {message: 'Email field is missing'})
} else {
var password = bcrypt.hashSync(_password, bcrypt.genSaltSync(10)); //encrypt password and store the hash...
var companySelected = JSON.parse(req.body.companySelected);
if (!req.user) {
checkCompanyRegistrationStatus(companySelected.company_number,
function(){
checkUserRegistrationStatus(_email,
function(){
checkPasswordStrength(_password,
function(){
maindb.MainDBInsert("INSERT INTO Uncomplete_Users_Registrations (first_name, last_name, password, email, company_registrat_number, company_name) OUTPUT Inserted.id VALUES (?, ?, ?, ?, ?, ?);",
[req.body.firstName, req.body.lastName, password, _email, companySelected.company_number, companySelected.title],
function(user, rowsCount){
return done(null, user[0]);
},
function(code, err){
return done(null, false, {message: err});
}
);
}, function (err) {
return done(null, false, {message: err});
})
}, function(err){
return done(null, false, {message: err})
}
)
}, function(err){
return done(null, false, {message: err})
}
)
}, function(err){
return done(null, false, {message: err})
}
)
} else {
// user is logged in and already has a local account. Ignore signup. (You should log out before trying to create a new account, user!)
return done(null, req.user);
}
}
}));

passport authentication: user undefined after login

I am trying to authenticate user ,when i try to login user after successful verification using req.logIn but it doesn't worked
router.post('/login', function(req, res, next) {
passport.authenticate('login',function (cb,data) {
//user verfication success
if(data){
req.logIn({user:"shamon"},function(err,result){
console.log("result",result,err)
res.send('login success');
});
}
})(req,res,next);
});
this console.log("result",result,err) gives me undefined,undefined
when i log req.user after logged i got undefined error
UPDATE
var LocalStrategy = require('passport-local').Strategy
module.exports = function(passport){
passport.use('local',new LocalStrategy({
usernameField: 'email',
passwordField: 'password'
},function (username,password,done) {
console.log('inside passport');
return done(null,true);
}));
passport.serializeUser(function(user, done) {
done(null, user);
});
passport.deserializeUser(function(user, done) {
done(null,user);
});
}
Just grab my implementation of password local-strategy. This is working for sure, but you will need to slightly modify it:
The strategy:
// Serialize
passport.serializeUser(function (user, done) {
done(null, user.id);
});
// Deserialize
passport.deserializeUser(function (id, done) {
User.findById(id, function (err, user) {
done(err, user);
});
});
passport.use('local-login', new LocalStrategy({
// by default, local strategy uses username and password, we will override with email
usernameField : 'email',
passwordField : 'password',
passReqToCallback : true // allows us to pass back the entire request to the callback
},
function(req, email, password, done) { // callback with email and password from our form
// find a user whose email is the same as the forms email
// we are checking to see if the user trying to login already exists
User.findOne({ 'local.email' : email }, function(err, user) {
// if there are any errors, return the error before anything else
if (err)
return done(err);
// if no user is found, return the message
if (!user)
return done(null, false, req.flash('loginError', 'No such user found.')); // req.flash is the way to set flashdata using connect-flash
// if the user is found but the password is wrong
if (!user.validPassword(password))
return done(null, false, req.flash('loginError', 'Oops! Wrong password.')); // create the loginMessage and save it to session as flashd
// all is well, return successful user
return done(null, user);
});
}
));
And the route:
router.post('/login', function(req, res, next) {
passport.authenticate('local-login', function(err, user, info) {
if (err) {
return next(err);
}
if (!user) {
return res.send({alert: req.flash('loginError')});
}
req.logIn(user, function(err) {
if (err) {
return next(err);
}
return res.send({redirect: '/'});
});
})(req, res, next);
});

Nodejs - Passport authenticate always return failure redirect

I'm making a form login by passportJs and it always return failureRedirect. I have search in stack overflow for this issue, but still not have the correct answer. Here is my code:
Form making form jade:
form(method='post', action='/users/login', enctype='multipart/form-data')
.form-group
label Username
input.form-control(name='username', type='text' placeholder='Enter Username')
.form-group
label Password
input.form-control(name='password', type='password' placeholder='Enter password')
input.btn.btn-default(name='submit', type='submit', value='Login')
Router Hanlde is using express framework form Nodejs and passport middleware:
passport.serializeUser(function(user, done) {
done(null, user.id);
});
passport.deserializeUser(function(id, done) {
User.getUserById(id, function(err, user) {
done(err, user);
});
});
passport.use(new LocalStrategy({
usernameField: 'username',
passwordField: 'password'
},
function(username, password, done) {
User.getUserByUsername(username, function(err, user) {
if (err) throw err;
if (!user) {
console.log('Unknown User');
return done(null, false, {
message: 'Unknown User'
});
}
User.comparePassword(password, user.password, function(err, isMatch) {
if (err) throw err;
if (isMatch) {
return done(null, user);
} else {
console.log('Invalid Password');
return done(null, false, {
message: 'Invalid Password'
});
}
});
});
}
));
router.post('/login', passport.authenticate('local', {
failureRedirect: '/users/login',
failureFlash: 'Invalid username or password'
}), function(req, res) {
console.log('Authentication Successful');
req.flash('success', 'You are logged in ');
res.redirect('/');
});
Looking at getUserByUsername function you shared in comments, it looks like you are not making call to callback function of getUserByUsername in correct way and therefore it is not getting user object resulting into failure redirect. The function you shared was:
module.exports.getUserByUsername = function(username, callback){
var query = {username: username};
User.findOne(query, callback);
}
Changing it to following should fix your issue:
module.exports.getUserByUsername = function(username, callback){
var query = {username: username};
User.findOne(query, function(err, user) {
callback(err, user);
});
}

Passport.js LocalStrategy logic

I want to understand how does LocalStrategy work.
Here is a part of my server file:
var passport = require('passport');
var express = require('express');
/* other initializations */
var app = express();
passport.use = new LocalStrategy(
function(email, password, done) {
module.exports.findByUsername(email, function(err, user){
if (err) throw err;
if(!user) {
done(null, false, { message: 'Incorrect username.' });
}
else if(user.password != password) {
done(null, false, { message: 'Incorrect password.' });
}
else {
return done(null, user);
}
});
}
)
app.post("/login"
, passport.authenticate('local',{
successRedirect : "/",
failureRedirect : "/login",
}) ,
function(){
console.log("post /login");
}
);
Now, from a client browser, I'm sending a http post request to http://localhost:8000/login . If authentication is success then user will be redirected to the root page "/" and if failure, user will be redirected to login page again.
The question is, when we are defining a new LocalStrategy, I define a function(email,password, done){...}. However, when I'm calling this function at app.post("/login", ...){...} how do I pass the email and password parameters?
passport assumes by default that you POST a form with input name='username' input name='password'. override it as described in passport docs:
passport.use(new LocalStrategy({
usernameField: 'email',
passwordField: 'password'
},
function(email, password, done) {
// ...
}
));

Categories

Resources