route.post failing to run passport.use - node.js

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.

Related

Why Callback not working with mongoose findOne method?

Using Expressjs and mongoose in a node application. I am trying to implement passportjs authentication. When I call the new LocalStrategy and passing the username and a callback function to get the username if exist, the callback function is not executing. To verify the I printed a console message is callback but even message is not showing. Why this is happening and how I can resolve it?
This is the router( index.js)
router.post('/login', (req, res, next) => {
console.log("Login POst called")
passport.authenticate('local', {
successRedirect: '/',
failureRedirect: '/login',
failureFlash: 'true'
})(req, res, next);
});
passport.use(new LocalStrategy(
(username, password, done)=>{
console.log("Local Strategy called")
User.getUserByUsername(username, (err, user)=>{
console.log("this message should display in callback"); // this message is not displaying
if(err) throw err;
if(!user){
return done(null, false, {message: "No user found"});
}
User.comparePassword(password, user.password, (err, isMatch)=>{
if(err) throw err;
if(isMatch){
return done(null, user);
}
else{
return done(null, false, {message: "Wrong Password"});
}
});
});
}
));
this is the model (User.js)
module.exports.getUserByUsername = (username, callback)=>{
console.log("GetUsername called")
const query = { username: username }
console.log(query);
User.findOne(query).exec(callback);
}
module.exports.getUserById = (id, callback)=>{
console.log("GetId called")
User.findId(id).exec(callback);
}

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")
})

Automatic failureRedirect in Passport

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??

I keep getting 401 Unauthorized whenever I try to login an existing user with JWT, Passport, and Express

Whenever I try to login a user through a post request in Postman, I keep getting this error:
Here is the localStrategy I made for checking if a user's email and password can be verified:
passport.use(new LocalStrategy({usernameField: 'email', passwordField: 'password'}, function(email, password, done){
User.findOne({email: email}, (err, user) => {
if (err) return done(err);
if (!user){
return done(null, false, {message: "User is not registered"});
}
else {
const realPassword = String(user.password);
bcrypt.compare(password, realPassword, (err, result) => {
if (err) throw err;
if (result){
console.log('result is...' + result);
done(null, user)
}
else {
console.log('result is...' + result);
return done(null, false, {message: 'Invalid Password'});
}
}
});
}));
And here is the post request method in my router file:
router.post('/login', passport.authenticate('local', {session: false}), (req, res, next) => {
function generateUserToken(user){
return jwt.sign({sub: user._id, creationDate: user.creationDate}, config.secretKey);
}
if (err) throw err;
res.send({token: generateUserToken(user)})
});
UPDATE: I changed some of my code now to address issues raised. However, now instead of getting unauthorized, I keep getting a 404 not found error
In my case there where dismatch in findOne(), User schema has local.email, so I needed to search for findOne({'local.email': email}, ...).
Seems the value of doesMatch is always false.
I believe you're missing the bcrypt.compare doesn't return anything.
It is asynchronous, so, you can't get the result using the return statement.
You have to put everygint inside of the callback function from bcrypt.compare
bcrypt.compare(password, realPassword, (err, result) => {
if (err) throw err;
// NOW YOU HAVE THE VALUE FORM THE COMPARISON
if (result){
done(null, user)
}
else {
return done(null, false, {message: 'Invalid Password'});
}
});
Let me know if it works.
Hope it helps you.

Resources