Automatic failureRedirect in Passport - node.js

I have a problem with my code. When I am trying to login without insert username and password
POST /user/login 302 1.289 ms - 32
GET /user/hehehehehe 404 6.310 ms - 1272
If i try to login with only login it's the same result
If i try to login with username and password correct or incorrect
500 Internal Server Error
Can someone tell me, where the mistake is?? That is first load failureRedirect. What is first thing I should check after trying to login??
router.post('/create', function (req, res, next) {
var newUser = {
username: req.body.username,
password: req.body.password
}
console.log(req.body)
req.checkBody('username', 'Login is required').notEmpty();
req.checkBody('password', 'Password is required').notEmpty();
var errors = req.validationErrors();
if (errors) {
console.log(errors)
res.send(errors);
} else {
bcrypt.hash(newUser.password, saltRounds, function (err, hash) {
if (err) {
console.log(err)
} else {
newUser.password = hash;
var user = new User(newUser);
user.save()
.then(function (User) {
res.send(User);
})
}
});
req.flash('success_msg', 'You are registered and can now login');
//res.redirect('/');
}
});
passport.use(new LocalStrategy(
function(username, password, done) {
User.getUserByUsername(username, function(err, user){
if(err) throw err;
if(!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 {
return done(null, false, {message: 'Invalid password'});
}
});
});
}));
passport.serializeUser( function(user, done) {
console.log('eheheheheh');
done(null, user.id);
});
passport.deserializeUser( function(id, done) {
User.getUserById(id, function(err, user) {
console.log('eheheheheh');
done(err, user);
});
});
router.post('/login',
passport.authenticate('local', { successRedirect:'hahahha', failureRedirect:'hehehehehe', failureFlash: true }),
function(req, res) {
console.log('yyy'),
res.redirect('dydydydy');
});
IMPORTANT
Which functions are loaded first?
1 - /login
Then this code?
passport.use(new LocalStrategy(
function(username, password, done) {
User.getUserByUsername(username, function(err, user){
if(err) throw err;
if(!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 {
return done(null, false, {message: 'Invalid password'});
}
});
});
}));
What mistakes might be here??

Related

how to send json data under passport local strategy

This is my passport Login Handler.
Now I want to send JSON Data under every condition so that API can access the response and on behalf of this display anything on frontend.
//Login Handler
passport.use('local-user', new LocalStrategy(
function(username, password, done) {
User.getUserByUsername(username, function(err, user){
if(err) {
console.log('error')
logger.log('error', 'Error Generates on User.getUserByUsername Query on users.js file');
throw err;
}
if(!user){
//res.send('unknown user');
console.log('Unknown User');
return done(null, false, {message: 'Unknown User'});
}
User.comparePassword(password, user.password, function(err, isMatch){
if(err) {
logger.log('error', 'Error Generates on User.comparePassword Query on users.js file');
throw err;
}
if(isMatch){
return done(null, user);
}else{
return done(null, false, {message: 'Invalid Credential, please check carefully...!'})
}
});
});
}
));
Anyone have any idea for this? Thanks in advance
The local strategy will pass the user or error with done(), then you receive that with a callback and pack it with res.json()
Here is my implementation. May help?
passport.use(
new LocalStrategy(
{
usernameField: "email"
},
function(username, password, done) {
User.findOne({ email: username }, function(err, user) {
if (err) {
return done(err);
}
if (!user) {
return done(null, false, {
email: "Email not found"
});
}
if (!user.validPassword(password)) {
return done(null, false, {
password: "Password is wrong"
});
}
return done(null, user);
});
}
)
);
router.post("/login", function(req, res) {
passport.authenticate("local", function(err, user, info) {
if (err) {
res.status(404).json(err);
return;
}
if (user) {
const token = user.generateJwt();
res.status(200);
res.json({
userInfo: user,
token: token
});
} else {
res.status(401).json(info);
}
})(req, res);
});

Passport LocalStrategy Not working on Two login system

So In My Project I am using two Login System. One for Admin i.e Seperate and other for users.
Already implemented Login System of Admin with The help of Passport.
Now when I am using same concept In user login system at that time Its not working. I mean It affect my admin Login.
My code is
passport.use(new LocalStrategy(
function(username, password, done) {
User.getUserByUsername(username, function(err, user){
if(err) throw err;
if(!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{
return done(null, false, {message: 'Invalid Credential, please check carefully...!'})
}
});
});
}
));
passport.serializeUser(function(user, done) {
done(null, user.id);
});
passport.deserializeUser(function(id, done) {
User.getUserById(id, function(err, user) {
done(err, user);
});
});
router.post('/login',
passport.authenticate('local', {
failureRedirect: '/user/login',
badRequestMessage: 'Field cannot be blank.!!', //missing credentials
failureFlash: true
}),
function(req, res) {
req.flash('success_msg', 'Welcome ' + req.user.name);
res.redirect('/user/dashboard');
});
I thought that LocalStrategy generate error so I aslo used basicStrategy but then My Admin Login Works Perfectly like earlier but my user login not works. Every time it Says Basic Realm = "Users".
Any Help will be Appreciate
Actually Its not on Local or Basic Strategy. It Totally depends on passport.serializeUser and deserializeUser.
We have to send User data, not user id on serializeUser. And on deserializeUser, we have to pick some uniqueness and then according to condition your query run. Actually, the deserializeUser function can handle Only one DB at a time of the query.
Try doing it this way. It creates two schemas one for admin and one or user. Accordingly create two local strategies by naming them and then we can serialize and deserialize the user based on their credentials. Hope this helps :)
app.get("/register", function(req, res){
res.render("reg")
})
app.post("/register", function(req, res){
var type = req.body.type
if(type=="student"){
var newUser = new Student({
username: req.body.username,
gender: req.body.gender,
rollnumber: req.body.rollnumber,
dob: req.body.dob,
email: req.body.email,
type: req.body.type,
password: req.body.password
})
req.checkBody('username','UserName is Required').notEmpty();
req.checkBody('rollnumber','Roll Number is Required').notEmpty();
req.checkBody('email','Email Required').notEmpty();
req.checkBody('email','Email Invalid').isEmail();
req.checkBody('password','Password is Required').notEmpty();
req.checkBody('password1','Passwords do not match').equals(req.body.password);
var errors = req.validationErrors();
if(errors){
res.render('Sregister', {errors: errors});
}else{
bcrypt.genSalt(10, function(err, salt){
bcrypt.hash(newUser.password, salt, function(err, hash){
if(!err){
newUser.password = hash;
}
newUser.save(function(err){
if(!err){
console.log("success in reg");
res.redirect("/student/login")
}
})
})
})
}}
else if(type=="teacher"){
var newUser = new Teacher({
username: req.body.username,
gender: req.body.gender,
rollnumber: req.body.rollnumber,
dob: req.body.dob,
email: req.body.email,
type: req.body.type,
password: req.body.password
})
req.checkBody('username','UserName is Required').notEmpty();
req.checkBody('rollnumber','Roll Number is Required').notEmpty();
req.checkBody('email','Email Required').notEmpty();
req.checkBody('email','Email Invalid').isEmail();
req.checkBody('password','Password is Required').notEmpty();
req.checkBody('password1','Passwords do not match').equals(req.body.password);
var errors = req.validationErrors();
if(errors){
res.render('Sregister', {errors: errors});
}else{
bcrypt.genSalt(10, function(err, salt){
bcrypt.hash(newUser.password, salt, function(err, hash){
if(!err){
newUser.password = hash;
}
newUser.save(function(err){
if(!err){
console.log("success in reg");
res.redirect("/teacher/login")
}
})
})
})
}}
})
//strategies
passport.use('student', new LocalStrategy(function(username, password, done){
var query = {username: username};
Student.findOne(query, function(err, student){
if(err) throw err;
if(!student){
return done(null, false);
}
bcrypt.compare(password,student.password, function(err, isMatch){
if(err) throw err;
if(isMatch)
return done(null, student);
else
return done(null,false);
})
})
}))
passport.use('teacher', new LocalStrategy(function(username, password, done){
var query = {username: username};
Teacher.findOne(query, function(err, teacher){
if(err) throw err;
if(!teacher){
console.log("no teach")
return done(null, false);
}
bcrypt.compare(password,teacher.password, function(err, isMatch){
if(err) throw err;
if(isMatch)
return done(null, teacher);
else
return done(null,false);
})
})
}))
//serialize deserizlize
passport.serializeUser(function (entity, done) {
done(null, { id: entity.id, type: entity.type });
});
passport.deserializeUser(function (obj, done) {
switch (obj.type) {
case 'student':
Student.findById(obj.id)
.then(user => {
if (user) {
done(null, user);
}
else {
done(new Error('user id not found:' + obj.id, null));
}
});
break;
case 'teacher':
Teacher.findById(obj.id)
.then(device => {
if (device) {
done(null, device);
} else {
done(new Error('device id not found:' + obj.id, null));
}
});
break;
default:
done(new Error('no entity type:', obj.type), null);
break;
}
});
//login routes
app.get("/student/login", function(req, res){
res.render("slogin")
})
app.get("/teacher/login", function(req, res){
res.render("tlogin")
})
app.post('/student/login',
passport.authenticate('student', { successRedirect: '/student/home', failureRedirect: '/student/login' }));
app.post('/teacher/login',
passport.authenticate('teacher', { successRedirect: '/teacher/home', failureRedirect: '/teacher/login' }));
app.get("/", function(req, res){
res.render("home");
})
app.get("/student/home", function(req, res){
res.send("hi student")
})
app.get("/teacher/home", function(req, res){
res.send("hi teacher")
})

Serialize different types of users in PassportJS

I have two local strategies for two different types of users: Students and Teachers. I am having trouble trying to login because my serialization is not working properly.
I have two models, Student and Teacher. Both have their separate collections, student and teacher with similar schema. Both have similar functions:
module.exports.getStudentByUsername = function(username, callback){
var query = {username: username};
User.findOne(query, callback);
}
module.exports.getStudentById = function(id, callback){
User.findById(id, callback);
}
module.exports.comparePassword = function(candidatePassword, hash, callback){
bcrypt.compare(candidatePassword, hash, function(err, isMatch) {
if(err) throw err;
callback(null, isMatch);
});
}
My two local strategies are:
passport.use('student-local', new LocalStrategy(
function(username, password, done) {
Student.getStudentByUsername(username, function(err, student){
if(err) throw err;
if(!student){
return done(null, false, {message: 'Unknown Student'});
}
Student.comparePassword(password, student.password, function(err, isMatch){
if(err) throw err;
if(isMatch){
return done(null, student);
} else {
return done(null, false, {message: 'Invalid password'});
}
});
});
}));
passport.use('teacher-local', new LocalStrategy(
function(username, password, done) {
Teacher.getTeacherByUsername(username, function(err, teacher){
if(err) throw err;
if(!teacher){
return done(null, false, {message: 'Unknown Teacher'});
}
Teacher.comparePassword(password, teacher.password, function(err, isMatch){
if(err) throw err;
if(isMatch){
return done(null, teacher);
} else {
return done(null, false, {message: 'Invalid password'});
}
});
});
}));
My two logins are:
router.post('/loginStudent',
passport.authenticate('student-local', {successRedirect:'/users/student', failureRedirect:'/login',failureFlash: true}),
function(req, res) {
res.redirect('/');
});
router.post('/loginTeacher',
passport.authenticate('teacher-local', {successRedirect:'/users/teacher', failureRedirect:'/login',failureFlash: true}),
function(req, res) {
res.redirect('/');
});
My serialization and deserialization are:
passport.serializeUser(function(user, done) {
if(Student.findOne({username: user.username}).length != 0) {
done(null, user.id);
} else if(Teacher.findOne({username: user.username}).length != 0) {
done(null, user.id);
}
});
passport.deserializeUser(function(id, done) {
if(Student.getStudentById(id)){
Student.getTeacherById(id, function(err, user) {
done(err, user);
});
} else {
Teacher.getTeacherById(id, function(err, user) {
done(err, user);
});
}
});
I know my serialization is wrong and that is why I am not being able to get this to work. When I tried with only one type of user and with the simpler serialization I found in the passport documents, my login was working fine.I am new with node and passport so any help would be highly appreciated.
I believe your serialization doesn't work, because the query for finding the teacher / student is actually async and you are treating it as sync.
passport.serializeUser(function(user, done) {
Student.findOne( { username: user.username }, function( err, student ) {
if ( student ) {
// user is student
done( null, user.id );
} else {
Teacher.findOne( { username: user.username }, function( err, teacher ) {
if ( teacher ) {
// user is teacher
done( null, user.id );
}
} );
}
} )
} );
This should work, although I'm not sure why you are doing to lookup for the type of user. You can just do :
passport.serializeUser(function(user, done) {
done(null, user.id);
} );

Passport local authentication is not working

I am building app using MEAN STACK. I want to use passport-local authentication for my login form. But a the time of form submission i am getting POST http://localhost/login 404 (Not Found) please have a look of my code below This is my controller:
lyfee.controller('loginCtrl', ['$scope', '$http', function($scope, $http) {
$scope.user = {};
$scope.login = function() {
// var data = {User: $scope.user }
//console.log($scope.user);
console.log("login function call");
$http.post('/login', $scope.user);
console.log("login request send");
}
}]);
and this is my server.js :
var passport = require('passport');
var LocalStrategy = require('passport-local').Strategy;
passport.use(new LocalStrategy(
function(username, password, done) {
User.getUserByusername(username, function(err, user) {
if (err) throw err;
if (!user) {
return done(null, false, {
message: 'Unknown USER'
});
}
User.comparePassword(password, user.password, function(err, isMatch) {
if () throw err;
if (isMatch) {
return done(null, user);
} else {
return done(null, false, {
message: 'Invalid password'
});
}
});
});
}));
app.post('/login',
passport.authenticate('local', {
successRedirect: '/',
failureRedirect: '/login',
failureFlash: true
}),
function(req, res) {
res.redirect('/');
});
in which file should i write getUserByusername and comparePassword function ? and what is mistake i am doing please correct it and give me some suggestion.
In your model suppose that User.js write functions like this:
/**
* Check the user's password
*/
dbSchema.methods.comparePassword = function(candidatePassword, cb) {
var status = this.password.localeCompare(candidatePassword.trim());
if (status != 0) {
return cb(err);
}
cb(null, true);
};
then use the function like this
passport.use(new LocalStrategy(
function(username, password, done) {
User.findOne({
username: username
}, function(err, user) {
if (err) throw err;
if (!user) {
return done(null, false, {
message: 'Unknown USER'
});
}
/**
* Check the user's password
*/
User.comparePassword(password, user.password, function(err, isMatch) {
if (err) throw err;
if (isMatch) {
return done(null, user);
} else {
return done(null, false, {
message: 'Invalid password'
});
}
});
});
}));

route.post failing to run passport.use

I'm being thrown a 302 error that I'm struggling to debug on submit, which I'm assuming is missing my passport.use for authentication. Can anyone see where I'm going wrong?
User.js
passport.use(new LocalStrategy(
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',
}),
// If user authenticates
function(req, res) {
console.log('Authentication successful');
req.flash('success', 'You are logged in');
res.redirect('/');
});
Model
module.exports.comparePassword = function(candidatePassword, hash, callback){
bcrypt.compare(candidatePassword, hash, function(err, isMatch){
if(err) return callback(err);
callback(null, isMatch);
});
};
module.exports.getUserById = function(id, callback){
User.findById(id, callback);
};
module.exports.getUserByUsername = function(username, callback){
var query = {username: username};
User.findOne(query, callback);
};
Jade
extends layout
block content
h1 Login
p Please login below
form(method='post',action='/users/login',enctype='multipart/form-data')
.form-group
label Username
input.form-control(name='username', type='text')
.form-group
label Password
input.form-control(name='password', type='password')
input.btn.btn-default(name='submit', type='submit',value='Login')
As far as I can tell everything should be firing normally. Or can anyone point me in the right direction to debug router.post?
Turns out the issue wasn't with Express or Passport.
After debugging further, I chased the 'undefined' variables from the form to uncover that the multipart/form-data' enctype was to blame.

Resources