I am running into an issue where I am trying to access my passport functions from my separate config file, but it doesn't appear that passport is being exposed when I require the file in my routes file. The error is occurring at .post(passportConfig.authenticate('local-login', {
Error:
has no method 'authenticate'
at Object. (/Users/user/Desktop/Projects/node/user-app/app/controllers/site-routes.js:68:23)`
passport.js (Passport authentication logic):
module.exports = function(passport){
var passport = require('passport');
var LocalStrategy = require('passport-local').Strategy;
var models = require('../models/db-index');
/*==== Passport Configuration ====*/
// Serialize sessions
passport.serializeUser(function(user, done) {
console.log(user.user_id + "Serializing");
done(null, user.user_id);
});
passport.deserializeUser(function(user_id, done) {
models.User.findById(user_id).then(function(user){
done(null, user);
}).error(function(err){
done(err, null);
});
});
//Login Logic
passport.use('local-login', new LocalStrategy({
usernameField: 'email',
passwordField: 'password',
passReqToCallback: true
},
function(req, email, password, done){
models.User.findOne({ where: { email : email }}).then(function(user) {
if (!user) {
done(null, false, req.flash('loginMessage', 'Unknown User'));
} else if (!user.validPassword(password)) {
done(null, false, req.flash('loginMessage', 'Wrong password'));
} else {
done(null, user);
}
}).catch(function(e) {
done(null, false, req.flash('loginMessage', e.name + " " + e.message));
});
}));
//Sign up Logic
passport.use('local-signup', new LocalStrategy({
usernameField: 'email',
passwordField: 'password',
passReqToCallback: true
}, function(req, email, password, done){
models.User.findOne({ where: { email: email }}).then(function(existingUser){
if (existingUser)
return done(null, false, req.flash('loginMessage', 'That email is already taken.'));
if (req.user) {
var user = req.user;
user.email = email;
user.password = models.User.generateHash(password);
user.save().catch(function (err){
throw err;
}).then(function(){
done(null, user);
});
} else {
var newUser = User.build({
email: email,
password: models.User.generateHash(password)
});
newUser.save().then(function(){ done(null, newUser);
}).catch(function(err){
done(null, false, req.flash('loginMessage', err));
});
}
}).catch(function(e){
done(null, false, req.flash('loginMessage',e.name + " " + e.message));
})
}));
};
site-routes.js:
var express = require('express');
var siteRoutes = express.Router();
var path = require('path');
var passportConfig = require(path.resolve(__dirname, '..', '..','./config/passport.js'));
var models = require('../models/db-index');
/*==== Index ====*/
siteRoutes.get('/', function(req, res){
res.render('pages/index.hbs');
});
siteRoutes.get('/flash', function(req, res){
req.flash('test', 'it worked');
res.redirect('/')
});
/*==== Login ====*/
siteRoutes.route('/login')
.get(function(req, res){
res.render('pages/login.hbs');
})
.post(passportConfig.authenticate('local-login', {
successRedirect: '/app',
failureRedirect: '/login',
failureFlash: 'Invalid username or password.'
}));
siteRoutes.route('/sign-up')
.get(function(req, res){
res.render('pages/sign-up.hbs');
})
.post(function(req, res){
models.User.create({
firstName: req.body.firstName,
lastName: req.body.lastName,
email: req.body.email,
password: req.body.password
}).then(function() {
res.redirect('/app');
//res.redirect('/sign-up/create-organization');
}).catch(function(error){
res.send(error);
})
});
module.exports = siteRoutes;
When you require config/passport.js, passportConfig will be initialized as a function, as you assigned a function to module.exports in your passport.js file. I'm referring to this line:
module.exports = function(passport){
What I'd do is to get rid of the function. Let the code execute and then assign passport to module.exports. .authenticate method is sitting on passport object.
Like this:
var passport = require('passport');
var LocalStrategy = require('passport-local').Strategy;
var models = require('../models/db-index');
/*==== Passport Configuration ====*/
// Serialize sessions
passport.serializeUser(function(user, done) {
console.log(user.user_id + "Serializing");
done(null, user.user_id);
});
passport.deserializeUser(function(user_id, done) {
models.User.findById(user_id).then(function(user){
done(null, user);
}).error(function(err){
done(err, null);
});
});
//Login Logic
passport.use('local-login', new LocalStrategy({
usernameField: 'email',
passwordField: 'password',
passReqToCallback: true
},
function(req, email, password, done){
models.User.findOne({ where: { email : email }}).then(function(user) {
if (!user) {
done(null, false, req.flash('loginMessage', 'Unknown User'));
} else if (!user.validPassword(password)) {
done(null, false, req.flash('loginMessage', 'Wrong password'));
} else {
done(null, user);
}
}).catch(function(e) {
done(null, false, req.flash('loginMessage', e.name + " " + e.message));
});
}));
//Sign up Logic
passport.use('local-signup', new LocalStrategy({
usernameField: 'email',
passwordField: 'password',
passReqToCallback: true
}, function(req, email, password, done){
models.User.findOne({ where: { email: email }}).then(function(existingUser){
if (existingUser)
return done(null, false, req.flash('loginMessage', 'That email is already taken.'));
if (req.user) {
var user = req.user;
user.email = email;
user.password = models.User.generateHash(password);
user.save().catch(function (err){
throw err;
}).then(function(){
done(null, user);
});
} else {
var newUser = User.build({
email: email,
password: models.User.generateHash(password)
});
newUser.save().then(function(){ done(null, newUser);
}).catch(function(err){
done(null, false, req.flash('loginMessage', err));
});
}
}).catch(function(e){
done(null, false, req.flash('loginMessage',e.name + " " + e.message));
})
}));
module.exports = passport;
Related
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);
}
I have a problem with passport.js, when I try to log into my account, I get an error: Error: Unknown authentication strategy "local-login". ". What's wrong with my code, thank you.
config/Passport.js
var passport = require('passport');
var request = require('request');
var LocalStrategy = require('passport-local').Strategy;
var User = require('../models/user'); // model User
passport.serializeUser(function (user, done) {
done(null, user.id);
});
passport.deserializeUser(function (id, done) {
User.findById(id, function (err, user) {
done(err, user);
});
});
passport.use('local-login', new LocalStrategy(function(username, password,
done) {
User.findOne({ username: username }, function(err, user) {
if (err) { return done(err); }
if (!user) {
return done(null, false, { msg: "Username" + username + "not found."
});
}
user.comparePassword(password, function(err, isMatch) {
if (err) { return done(err); }
// Make sure the user has been verified
if (isMatch) {
return done(null, user);
}
return done(null, false, { msg: 'Invalid email or password.' });
});
});
}));
app.js
var session = require('express-session');
var passport = require('passport');
app.use(session({
secret: config.secret,
resave: true,
saveUninitialized: true,
cookie: { maxAge: 1*15*1000 }
}));
app.use(passport.initialize());
app.use(passport.session());
app.use(function(req, res, next) {
res.locals.user = req.user;
next();
});
routes/authRoutes.js
app.post('/login', function(req, res, next) {
passport.authenticate('local-login', function(err, user, info) {
if (err) { return next(err); }
if (!user) {
return res.redirect('/login');
}
req.login(user, function(err) {
if (err) { return next(err); }
res.redirect('/');
});
})(req, res, next);
});
It must be 'local' instead of 'local-login'
module.exports.login_post = passport.authenticate('local', {
successRedirect: '/',
failureRedirect: '/',
failureFlash: true
});
I Use MySQL. It's the complete code:
passport.use(new LocalStrategy({
passReqToCallback: true
}, function(req, username, password, done) {
pool.query("SELECT * FROM user WHERE username = ?",[username], function(err, rows, fields) {
if (err) throw err;
console.log('checked');
if(!isExist(username) || !isExist(password)){
return done(null, false, req.flash('message_err', 'Username and password cant be emptied!.'));
}
if (!rows[0]) {
return done(null, false, req.flash('message_err', 'Oops! Username or password didnt match.'));
}
if (!bcrypt.compareSync(password, rows[0].password)) {
return done(null, false, req.flash('message_err', 'Oops! Username/password didnt match.'));
}
return done(null, rows[0]);
});
}));
passport.deserializeUser(function(user, done) {
console.log('user : ' + user);
pool.query("SELECT * FROM user WHERE username = ?", [user], function(err, rows, fields) {
if(err) throw err;
console.log('deserialized');
done(err, rows[0]);
});
});
//serialize and deserialize passport
passport.serializeUser(function(req, user, done) {
console.log('serialized');
done(null, user.username, req.flash('message_success', 'Welcome, '+user.username + "!"));
});
module.exports.login_post = passport.authenticate('local', {
successRedirect: '/',
failureRedirect: '/',
failureFlash: true
});
First, i have this in my route, i need to use Passport to Authenticate the User Sign Up Process :
router.post('/user/signup', passport.authenticate('local.signup',{
successRedirect: '/user/profile',
failureRedirect: '/user/signup',
failureFlash: true
}));
I'm learning Node JS from Youtube Video, in the tutorial, there is a step to create Folder called "config", and inside the "config" folder, there is a file called "passport.js".
The problem is, there is "req" parameter inside one of the function in this "passport.js". When i try to run my program, there is an error that said, "req is not defined". this is the source code of "passport.js" :
var express = require('express');
var passport = require('passport');
var User = require('../models/user');
var LocalStrategy = require('passport-local').Strategy;
passport.serializeUser(function(user, done){
done(null, user.id);
});
passport.deserializeUser(function(id, done){
User.findById(id, function(err, user){
done(err, user);
});
});
passport.use('local.signup', new LocalStrategy({
usernameField: 'email',
passwordField: 'password',
passReqToCallBack: true
}, function(req, email, password, done){ //here is the problem
console.log('REQ :');
console.log(req);
console.log('password :');
console.log(email);
console.log('email :');
console.log(password);
console.log('done :');
console.log(done);
req.checkBody('email','Invalid Email').notEmpty().isEmail();
req.checkBody('password','Invalid password').notEmpty().isLength({min:4});
var errors = req.validationErrors();
if(errors){
var message = [];
errors.forEach(function(error){
message.push(error.msg);
});
return done(null, false, req.flash('error', messages));
}
User.findOne({'email': email}, function(err, user){
if(err){
return done(err);
}
if(user){
return done(null, false, {message: 'Email is already in use.'});
}
var newUser = new User();
newUser.email = email;
newUser.password = newUser.encryptPassword(password);
newUser.save(function(err, result){
if(err){
return done(err);
}
return done(null, newUser);
});
});
}));
How to bring the req to fill the parameter in the passport.js ?
The parameter is called passReqToCallback, not passReqToCallBack (notice that the b needs to be lower-case).
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);
});
So I am trying to add local authentication to my MEAN stack app.
Everything was running smoothly. Sign up works great. But I cannot log in as a user.
I am getting:
POST /login 302 3.979 ms - 58
on the console (via Morgan)
But there is certainly an error (express routes to the "failureRedirect" set via passport)
Could it be a problem reading from the db? Why would I be able to write to it then...
A test with chai reveals that the program cannot "find user by email" from the db via User Model
anyone have any clue why this is happening?
Here is my passport strategy code:
/config/passport.js
var LocalStrategy = require('passport-local').Strategy;
var User = require('../models/users');
module.exports = function(passport) {
// passport session setup ==================================================
passport.serializeUser(function(user, done) {
done(null, user.id);
});
passport.deserializeUser(function(id, done) {
User.findById(id, function(err, user) {
done(err, user);
});
});
// local login =============================================================
passport.use('local-login', new LocalStrategy({
usernameField : 'email',
passwordField : 'password',
passReqToCallback : true
},
function(req, email, password, done) {
User.findOne({ 'local.email' : email }, function(err, user) {
if (err)
return done(err);
if (!user)
return done(null, false, req.flash('loginMessage', 'No user found.'));
if (!user.validPassword(password))
return done(null, false, req.flash('loginMessage', 'Oops! Wrong password.'));
return done(null, user);
});
}));
// local sign up =============================================================
passport.use('local-signup', new LocalStrategy({
usernameField : 'email',
passwordField : 'password',
passReqToCallback : true
},
function(req, email, password, done) {
User.findOne({ 'local.email' : email }, function(err, user) {
if (err)
return done(err);
if (user) {
return done(null, false, req.flash('signupMessage', 'That email is already taken.'));
} else {
var newUser = new User();
newUser.local.email = email;
newUser.local.password = newUser.generateHash(password); // use the generateHash function in our user model
newUser.save(function(err) {
if (err)
throw err;
return done(null, newUser);
});
}
});
}));
};
Here's the routes:
// /login ======================================================================
app.route('/login')
.get(function(req, res) {
res.setHeader('Content-Type', 'text/html');
res.render('login.html');
})
.post(passport.authenticate('local-login', {
successRedirect : '/profile',
failureRedirect : '/'
}));
// /signup ======================================================================
app.route('/signup')
.get(function(req, res) {
res.setHeader('Content-Type', 'text/html');
res.render('signup.html');
})
.post(passport.authenticate('local-signup', {
successRedirect : '/profile',
failureRedirect : '/'
}));
Login Strategy
// passport/login.js
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 error & redirect back
if (!user){
console.log('User Not Found with username '+username);
return done(null, false,
req.flash('message', 'User Not found.'));
}
// User exists but wrong password, log the error
if (!isValidPassword(user, password)){
console.log('Invalid Password');
return done(null, false,
req.flash('message', 'Invalid Password'));
}
// User and password both match, return user from
// done method which will be treated like success
return done(null, user);
}
);
}));
We now define our routes for the application in the following module which takes the instance of Passport created in app.js above. Save this module in
module.exports = function(passport){
/* GET login page. */
router.get('/', function(req, res) {
// Display the Login page with any flash message, if any
res.render('index', { message: req.flash('message') });
});
/* Handle Login POST */
router.post('/login', passport.authenticate('login', {
successRedirect: '/home',
failureRedirect: '/',
failureFlash : true
}));
/* GET Registration Page */
router.get('/signup', function(req, res){
res.render('register',{message: req.flash('message')});
});
/* Handle Registration POST */
router.post('/signup', passport.authenticate('signup', {
successRedirect: '/home',
failureRedirect: '/signup',
failureFlash : true
}));
return router;
}