Unable to signup users with passport-local - node.js

I'm trying to use a local passport to login and signup in my app.
But when I send a post request from my signup form, the user is being redirected to the signup form.
This is the route definition:
app.post('/signup', passport.authenticate('local-signup', {
successRedirect : '/profile', // redirect to the secure profile section
failureRedirect : '/signup', // redirect back to the signup page if there is an error
failureFlash : true // allow flash messages
}));
This is my config/passport.js
var LocalStrategy = require('passport-local').Strategy;
var User = require('../models/user');
var mysql = require('mysql');
var connection = mysql.createConnection({
host : process.env.MYSQL_HOST,
user : process.env.MYSQL_USER,
password : process.env.MYSQL_PASSWORD,
database : process.env.MYSQL_DB
});
module.exports = function(passport) {
passport.serializeUser(function(user, done) {
console.log("abc serializeUser");
console.log(user);
done(null, user.id);
});
passport.deserializeUser(function(id, done) {
console.log("abc deserializeUser");
User.findById(id).then(function(user){
done(null, user);
}).catch(function(e){
done(e, false);
});
});
passport.use('local-signup', new LocalStrategy(
function(username, password, done) {
console.log("abc local signup");
User.findOne({where: {username: username}}).then(function(err, user) {
if (err) { return done(err); }
if (!user) {
console.log('Incorrect username.');
return done(null, false, { message: 'Incorrect username.' });
} else if (password != user.password) {
console.log('Incorrect password');
return done(null, false, { message: 'Incorrect password.' });
} else {
console.log('ok');
done(null, user);
}
});
}
));
};
This is the models/user.js
"use strict";
module.exports = function(sequelize, DataTypes) {
var User = sequelize.define("User", {
email: DataTypes.STRING,
password: DataTypes.STRING,
token: DataTypes.STRING
}
);
return User;
};

Sequelize's .then() receives result only, errors should be handled by .catch() block. So the query will looks like this:
User.findOne({where: {username: username}}).then(function(user) {
if (!user) {
console.log('Incorrect username.');
return done(null, false, { message: 'Incorrect username.' });
} else if (password != user.password) {
console.log('Incorrect password');
return done(null, false, { message: 'Incorrect password.' });
} else {
console.log('ok');
done(null, user);
}
}).catch(function(err){
done(err);
});

Related

What is wrong with this ExpressJS + Passport signup route? It returns 400 Bad Request

I implemented a signup route below. It gets to "User saved..." but the request returns 404.
It doesn't seem to be executing the login strategy:
router.post("/signup", function(req, res, next) {
var email = req.body.email;
var password = req.body.password;
User.findOne({ email: email }, function(err, user) {
if (err) { return next(err); }
if (user) {
return res.status(409).send({message: "Duplicate user - already registered."});
}
var newUser = new User({
email: email,
password: password
});
newUser.save(next);
console.log("User saved...");
});
},
passport.authenticate("login"),
function(req, res) {
return res.status(200).send({
message: "Signup successful",
user: req.user
});
}
);
My Passport login strategy looks like this:
passport.use("login", new LocalStrategy(async (email, password, done) => {
console.log("login...");
User.findOne({ email: email }, function(err, user) {
if (err) { return done(err); }
if (!user) {
return done(null, false, { message: "No user has that email!" });
}
user.checkPassword(password, function(err, isMatch) {
console.log("Checked password...");
console.log("Error? Match?");
console.log(err);
console.log(isMatch);
if (err) { return done(err); }
if (isMatch) {
console.log("Returning done...");
return done(null, user, { message: 'Logged in Successfully' });
} else {
return done(null, false, { message: "Invalid password." });
}
});
});
}));
Here's what I see in the logs:
User saved...
POST /signup 400 181.122 ms - -
Passport is likely throwing the 400 error because the username/password fields are not set.
Passport expects username and password and what you are passing are the email and password. So you can modify the code and let passport's LocalStrategy use the email as the username.
You can set the username and password as follows:
passport.use("login", new LocalStrategy({
usernameField: 'email',
passwordField: 'password',
},async (usernameField, passwordField, done) => {
console.log("login...");
User.findOne({ email: usernameField }, function (err, user) {
if (err) { return done(err); }
if (!user) {
return done(null, false, { message: "No user has that email!" });
}
user.checkPassword(passwordField, function (err, isMatch) {
console.log("Checked password...");
console.log("Error? Match?");
console.log(err);
console.log(isMatch);
if (err) { return done(err); }
if (isMatch) {
console.log("Returning done...");
return done(null, user, { message: 'Logged in Successfully' });
} else {
return done(null, false, { message: "Invalid password." });
}
});
});
}));
You can check the line which was throwing the error from passport's source code here

Password validation in nodejs using passport js

I'm using passport js local strategy for authentication and nodejs. problem is when i try to login with wrong password, I still redirects to success page.
what i have to do
this is login strategy
const passport = require('passport')
const LocalStratery = require('passport-local').Strategy;
const User = require('../models/userAuth')
passport.serializeUser(function(user, done) {
done(null, user.id);
});
// used to deserialize the user
passport.deserializeUser(function(id, done) {
User.findById(id, function(err, user) {
done(err, user);
});
});
passport.use('local-login', new LocalStratery({
usernameField: 'email',
passwordField: 'password',
passReqToCallback: true
}, function(req, email, password, done) {
console.log(email)
console.log(password)
User.findOne({email: email})
.then((err, user) => {
if(err) {
return done(null, err, req.flash('unkonown', 'there was an error,
please try after sometime'))
}
if(!user) {
console.log(user)
return done(null, false, req.flash('NotExists', 'no user
exixts'))
}
if(!user.validpass(password)){
return done(null, false, req.flash('passFail', 'password not
matches'))
}
if(user) {
return done(null, user, req.flash('success', 'login success'))
}
})
.catch(err => {
throw err
})
}))
user model using mongoose
userAuth.methods.excryptPass = function(password) {
return bcrypt.hashSync(password, bcrypt.genSaltSync(5), null)
}
userAuth.methods.validpass = (password) => {
return bcrypt.compareSync(password, this.password);
}

User Authentication on MEAN stack application

I am building an API using the MEAN stack and am working on the login and signup functions.
And I want to respond with a json string as follows
{
success: 0,
message: ""
}
success:1 for successful login and 0 otherwise.
My authenticate.js is as follows
module.exports = function(passport){
//log in
router.post('/login', passport.authenticate('login', {
//success
//failure
}));
//sign up
router.post('/signup', passport.authenticate('signup', {
//success
//failure
}));
//log out
router.get('/signout', function(req, res) {
req.logout();
res.redirect('/');
});
return router;
}
My passport.init.js middleware is as follows
var mongoose = require('mongoose');
var User = mongoose.model('User');
var LocalStrategy = require('passport-local').Strategy;
var bCrypt = require('bcrypt-nodejs');
module.exports = function(passport){
// Passport needs to be able to serialize and deserialize users to support persistent login sessions
passport.serializeUser(function(user, done) {
console.log('serializing user:',user.username);
done(null, user._id);
});
passport.deserializeUser(function(id, done) {
User.findById(id, function(err, user) {
console.log('deserializing user:',user.username);
done(err, user);
});
});
passport.use('login', new LocalStrategy({
passReqToCallback : true
},
function(req, username, password, done) {
// check in mongo if a user with username exists or not
User.findOne({ 'username' : username },
function(err, user) {
// In case of any error, return using the done method
if (err)
return done(err);
// Username does not exist, log the error and redirect back
if (!user){
console.log('User Not Found with username '+username);
return done(null, false);
}
// User exists but wrong password, log the error
if (!isValidPassword(user, password)){
console.log('Invalid Password');
return done(null, false); // redirect back to login page
}
// User and password both match, return user from done method
// which will be treated like success
return done(null, user);
}
);
}
));
passport.use('signup', new LocalStrategy({
passReqToCallback : true // allows us to pass back the entire request to the callback
},
function(req, username, password, done) {
// find a user in mongo with provided username
User.findOne({ 'username' : username }, function(err, user) {
// In case of any error, return using the done method
if (err){
console.log('Error in SignUp: '+err);
return done(err);
}
// already exists
if (user) {
console.log('User already exists with username: '+username);
return done(null, false);
} else {
// if there is no user, create the user
var newUser = new User();
// set the user's local credentials
newUser.username = username;
newUser.password = createHash(password);
// save the user
newUser.save(function(err) {
if (err){
console.log('Error in Saving user: '+err);
throw err;
}
console.log(newUser.username + ' Registration succesful');
return done(null, newUser);
});
}
});
})
);
var isValidPassword = function(user, password){
return bCrypt.compareSync(password, user.password);
};
// Generates hash using bCrypt
var createHash = function(password){
return bCrypt.hashSync(password, bCrypt.genSaltSync(10), null);
};
};
Please help me out in passing the JSON string accordingly
Using Express, all you have to do is to execute res.json inside any controller, passing it any JavaScript object. Express will automatically convert it to JSON and return it to the user.
return res.json({ success: 0, message: '' }

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'
});
}
});
});
}));

How to display error message using passport in view

I want to display error or succuss message during authentication using passport,my code in passport.js is:
var passport = require('passport');
var flash = require('connect-flash');
var LocalStrategy = require('passport-local').Strategy,
User = require(process.cwd() + '/app/models/user');
module.exports = function() {
passport.use(new LocalStrategy({
usernamelocal: 'userid',
passwordlocal: 'password'
},
function(username, password, done) {
User.findOne({
userid: username
}, function(err, user) {
if (err)
return done(err);
if (!user) {
console.log("*************user name error");
this.message = "user error";
return done(null, false, {
message: 'unknown user'
});
}
if (user.deleted) {
console.log("user deleted error");
return done(null, false, {
message: 'unknown user'
});
}
});
}
));
}

Resources