Passport error when serialize with another strategy - node.js

Create a new type of login for a different type of user (another list in the database), the login succeeds but it doesn't serialize me grow and then show it (just like it does for user). Any idea what it could be ?
Passport Config:
const passport = require('passport');
const LocalStrategy = require('passport-local').Strategy;
var User = require('../model/User')();
var Grow = require('../model/Grow')();
passport.use('local', new LocalStrategy({
usernameField: 'email'
}, async (email, password, done) => {
// Match Email User
const user = await User.findOne({ email: email });
if (!user) {
return done(null, false, { message: 'No se encontro el usuario' });
} else {
// Match Password User
const match = await user.matchPassword(password);
if (match) {
return done(null, user);
} else {
return done(null, false, { message: 'ContraseƱa incorrecta' });
}
}
}));
passport.serializeUser((user, done) => {
done(null, user.id);
});
passport.deserializeUser((id, done) => {
User.findById(id, (err, user) => {
done(err, user);
});
});
passport.use('growlocal', new LocalStrategy({
usernameField: 'email'
}, async (email, password, done) => {
const grow = await Grow.findOne({ email: email });
if (!grow) {
return done(null, false, { message: 'No se encontro el usuario' });
} else {
const match = await grow.matchPassword(password);
if (match) {
return done(null, grow);
} else {
return done(null, false, { message: 'ContraseƱa incorrecta' });
}
}
}));
passport.serializeUser((grow, done) => {
console.log(grow)
done(null, grow.id);
});
passport.deserializeUser((id, done) => {
console.log(grow)
Grow.findById(id, (err, grow) => {
done(err, grow);
});
});
Router Config:
// Login Grow
router.get('/grows/signin', (req, res) => {
res.render('growlogin');
});
router.post('/grows/signin', passport.authenticate('growlocal', {
successRedirect: '/',
failureRedirect: '/grows/signin',
failureFlash: true
}));
EJS:
<% if (grow){ %>
Gato
<%}%>
Error:
If anyone has any idea how to fix it, please let me know. It is very important for the development of my application. Thank you very much <3

Related

Passport authentication does nothing

I am using passport for authentication. The code doesn't giving any errors but does nothing when I use the right credentials. I tried console log in the authenticateUser function and serializeUser function, it does print statements in both.
My passportConfig.js file
const LocalStrategy = require('passport-local').Strategy;
const db = require('../postgresql');
const bcrypt = require('bcrypt');
function initialize(passport) {
const authenticateUser = async (email, password, done) => {
try {
const user = await db.oneOrNone('SELECT * FROM users WHERE email = $1', [email]);
if(user) {
if(!bcrypt.compareSync(password, user.password)) {
return done(null, false, { message: "Email or password is incorrect"});
}
else {
console.log('Authenticated user');
return done(null, user);
}
}
else {
return done(null, false, { message: "Email or password is incorrect"});
}
}
catch (err) {
console.log(err);
}
}
passport.use(
new LocalStrategy({
usernameField: 'email',
passwordField: 'password'
}, authenticateUser
)
);
passport.serializeUser((user, done) => {
console.log('Serialized user');
done(null, user.id)
});
passport.deserializeUser(async (id, done) => {
try {
const user = await db.oneOrNone('SELECT * FROM users WHERE id = $1', [id]);
return done(null, user);
}
catch(err) {
console.log(err);
}
});
}
module.exports = initialize;
Snippet of my route file
router.post('/login', passport.authenticate('local', {
successRedirect: '/',
failureRedirect: '/login',
failureFlash: true
}));

I'm trying to implement passport-local but i'm getting error

This is the error I'm getting in passport.js config. I don't understand what it means: Why passport.use is not a function?
TypeError: passport.use is not a function
This is my code:
const LocalStrategy = require('passport-local').Strategy;
const passport = require('passport');
const mongoose = require('mongoose');
const bcrypt = require('bcryptjs');
// load user models
const User = require('../models/Users');
module.exports = function (passport) {
passport.use (
new LocalStrategy({ usernameField: 'email' }, (email, password, done) => {
// Match User
User.findOne({ email: email })
.then((user) => {
if (!user) {
return done(null, false, { message: 'Email is not registered' })
}
})
.catch((err) => {
console.log(err);
})
// match password
bcrypt.compare(password, user.password, (err, isMatch) => {
if (err) throw (err)
if (isMatch) {
return done(null, user)
} else {
return done(null, false, { message: 'Incorrect Password' })
}
})
})
);
passport.serializeUser((user, done) => {
done(null, user.id);
});
passport.deserializeUser( (id, done) => {
User.findById(id, (err, user) => {
done(err, user);
});
});
}
passport.js
const passport = require("passport")
const LocalStrategy = require('passport-local').Strategy;
const User = require('./models/user');
// Local Strategy
passport.use(new LocalStrategy({
usernameField: 'email'
}, async (email, password, done) => {
try {
// find the user given the email
const user = await User.findOne({ "email": email });
// if not, handle it
if (!user) {
return done(null, false);
}
// check if password is correct
const isMatch = await user.isValidPassword(password);
// if not handle it
if (!isMatch) {
return done(null, false);
}
// otherwise return the user
done(null, user);
} catch (error) {
done(error, false);
}
}));

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

How to configure and package passport as a one module?

I test my routes in Advanced Rest Client, and with my code the output is 401, Unauthorized. I don't understand why this is happening.
I packaged my authentication in one module. Then, I invoke it in my server file with wagner-core(dependency injector):
wagner.invoke(require('./passport-init'),{ app: app })
passport.js:
'use strict'
const bCrypt = require('bcryptjs')
const passport = require('passport')
const LocalStrategy = require('passport-local').Strategy
const session = require('express-session')
module.exports = (User, app) => {
passport.serializeUser((user, done) => {
done(null, user._id)
})
passport.deserializeUser((id, done) => {
User.findOne({ _id: id }).exec(done)
})
passport.use('login', new LocalStrategy({ passReqToCallback: true }, (req, username, password, done) => {
User.findOne({ username: username }, (err, user) => {
if (err) { return done(err) }
if (!user) { return done(null, false, { message: 'Invalid username' }) }
if (!isValidPassword(user, password)) {
return done(null, false, { message: 'Invalid password' })
}
return done(null, user)
})
}))
app.use(session({
secret: process.env.SESSION_SECRET || 'secret',
resave: false,
saveUninitialized: false
}))
app.use(passport.initialize())
app.use(passport.session())
app.post('/login', passport.authenticate('login'), (req, res) => {
res.redirect('/users/' + req.user.username)
})
}
function isValidPassword (user, password) {
return bCrypt.compareSync(password, user.password)
}
I figured it out. It was something to do with my routes, and isValidpassword function.
Heres the amended code:
'use strict'
const bCrypt = require('bcryptjs')
const passport = require('passport')
const LocalStrategy = require('passport-local').Strategy
const session = require('express-session')
module.exports = (User, app) => {
passport.serializeUser((user, done) => {
done(null, user._id)
})
passport.deserializeUser((id, done) => {
User.findById(id, (err, user) => {
done(err, user)
})
})
passport.use('login', new LocalStrategy({ passReqToCallback: true }, (req, username, password, done) => {
process.nextTick(() => {
User.findOne({ username: username }, (err, user) => {
if (err) { return done(err) }
if (!user) { return done(null, false, { message: 'Invalid username' }) }
if (!user.password) {
bCrypt.compareSync(password, user.password)
return done(null, false, { message: 'Invalid password' })
}
return done(null, user)
})
})
}))
passport.use('signup', new LocalStrategy({ passReqToCallback: true }, (req, username, password, done) => {
process.nextTick(() => {
User.findOne({ username: username }, (err, user) => {
if (err) { return done(err) }
if (user) {
return done(null, false, { message: 'User already exists' })
} else {
let newUser = new User()
newUser.username = req.body.username
newUser.password = createHash(req.body.password)
newUser.save((err) => {
if (err) throw err
return done(null, newUser)
})
}
})
})
}))
app.use(session({
secret: 'secret',
resave: false,
saveUninitialized: false
}))
app.use(passport.initialize())
app.use(passport.session())
app.get('/success', (req, res) => {
res.send({ state: 'success', user: req.user ? req.user : null })
})
app.post('/login', passport.authenticate('login', {
successRedirect: '/success',
failureRedirect: '/fail'
}))
app.post('/signup', passport.authenticate('signup', {
successRedirect: '/success',
failureRedirect: '/fail'
}))
}
function createHash (password) {
return bCrypt.hashSync(password, bCrypt.genSaltSync(10), null)
}

Failed to serialize user into session when using passport-facebook strategy with passport-local

I am using passport-local and passport-facebook strategies for authentication in sails.js. Authentication with email is working fine. But when user authenticates using facebook, I am getting this error message [Error: Failed to serialize user into session].
Then I tested serializeUser method and it turns out user param is empty in case of facebook. While I also tried to see if verifyHandler is called or not and it is not being called.
Here is my code for the facebook authentication action:
facebook: function (req, res) {
passport.authenticate('facebook', {failureRedirect: '/login', scope: ['email']}, function (err, user) {
if ((err) || (!user)) {
req.session.flash = {
errMsg: 'Email or password mismatch.'
}
return res.redirect('/login');
}
req.logIn(user, function (err) {
if (err) {
console.log(err);
res.view('500');
return;
}
res.redirect('/');
return;
});
})(req, res);
}
And this is the code of passport.js service (api/services/passport.js)
var passport = require('passport'),
LocalStrategy = require('passport-local').Strategy,
FacebookStrategy = require('passport-facebook').Strategy,
bcrypt = require('bcrypt');
var verifyHandler = function (token, tokenSecret, profile, done) {
console.log('in verifyHandler'); // this line is not being executed.
console.log(profile);
process.nextTick(function () {
User.findOne({uid: profile.id}, function (err, user) {
if (err) {
return done(err);
}
if (user) {
return done(null, user);
} else {
var data = {
provider: profile.provider,
uid: profile.id,
name: profile.displayName
};
if (profile.emails && profile.emails[0] && profile.emails[0].value) {
data.email = profile.emails[0].value;
}
User.create(data, function (err, user) {
return done(err, 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(new LocalStrategy({
usernameField: 'email',
passwordField: 'password'
},
function (email, password, done) {
User.findOne({email: email}).exec(function (err, user) {
if (err) {
return done(err);
}
if (!user) {
return done(null, false, {message: 'Unknown user ' + email});
}
bcrypt.compare(password, user.password, function (err, res) {
if (!res) return done(null, false, {message: 'Invalid Password'});
return done(null, user);
});
});
}
));
passport.use(new FacebookStrategy({
clientID: sails.config.facebook.clientID,
clientSecret: sails.config.facebook.clientSecret,
callbackURL: sails.config.facebook.callbackURL
}, verifyHandler));
And finally (config/passport.js)
var passport = require('passport'),
LocalStrategy = require('passport-local').Strategy,
FacebookStrategy = require('passport-facebook').Strategy;
module.exports = {
http: {
customMiddleware: function (app) {
app.use(passport.initialize());
app.use(passport.session());
}
}
};
Any thoughts?
Check if user.id is defined and it is string but not ObjectId().
in
passport.serializeUser(function (user, done) {
done(null, user.id);
});

Resources