Below is my registration strategy in passportJS. Most of the code runs fine until right at the bottom where I go to res.send the user argument after the passport.authenticate method has successfully authenticated the strategy. However whenever I am sent back the response I receive a page with a "false" message. Instead of sending me the users details I am sent "false" instead.
app.use(passport.initialize());
app.use(passport.session());
passport.serializeUser(function(user, done) {
return done(null, user.id);
});
passport.deserializeUser(function(id, done) {
User.findById(id, function(err, user) {
done(err, user);
});
});
passport.use("registerUser",
new LocalStrategy({ passReqToCallback: true },
function(req, username, password, done) {
var newUser = new User({
name: username,
email: req.body.email,
password: password
});
newUser.save(function(err) {
if (err) {
return done(err);
}
return done(null, newUser);
});
}));
app.get("/", function(req, res) {
res.render("index", { title: "Register!", url: req.url });
});
app.post("/", function(req, res, next) {
passport.authenticate("registerUser", function(err, user) {
if (err) {
return done(err);
}
res.send(user);
})(req, res, next);
});
You should use passport.authenticate() as a second argument before function(req, res):
`app.post('/', passport.authenticate('registerUser', function(err, user) {
if (err) return done(err);
if (!user) return done(null, false);
done(null, user);
}), function(req, res) {
res.send(user);
});`
This way you introduced authentication middleware that will run before the response. Have a look here: https://github.com/passport/express-4.x-local-example/blob/master/server.js
Related
Login is not occurring instead the failure redirect is calling repeatedly.
The password and username already exist so that may not be the issue.
Router file
router.post('/login', function (req, res, next) {
passport.authenticate('local',{
successRedirect: '/',
failureRedirect: '/user/register_login',
failureFlash: 'Invalid username or password.'
})(req, res, next);
});
passport.js file
var LocalStrategy = require('passport-local').Strategy;
var User = require('../models/user');
var bcrypt = require('bcryptjs');
var alert= require('alert');
module.exports = function (passport) {
passport.use(new LocalStrategy(function (email, password, done) {
User.findOne({email: email}, function (err, user) {
if (err)
console.log(err);
alert(err);
if (!user) {
return done(null, false);
alert('No user found!');
console.log(message);
}
bcrypt.compare(password, user.password, function (err, isMatch) {
if (err)
console.log(err);
if (isMatch) {
return done(null, user);
console.log("ohk");
}
else {
return done(null, false);
console.log(message);
alert('Incorrect Password');
}
});
});
}));
passport.serializeUser(function (user, done) {
done(null, user.id);
});
passport.deserializeUser(function (id, done) {
User.findById(id, function (err, user) {
done(err, user);
});
});
}
I took a tutorial from the odin project on passport and it worked so I decided to implement what I learned on my own project, the difference between theirs and mine is that I was following a design pattern while they weren't and I can't seem to find the problem as to why it is not responding .
in my login page I use the email and password and I've tried changing the below code many times.
this is the controller.js
//passport functions
passport.use(
new LocalStrategy((username, password, done) => {
User.findOne({ username: username }, (err, user) => {
console.log(user)
if (err) {
return done(err);
};
if (!user) {
return done(null, false, { msg: "Incorrect username" });
}
if (user.password !== password) {
return done(null, false, { msg: "Incorrect password" });
}
return done(null, user);
});
})
);
passport.serializeUser(function(user, done) {
done(null, user.id);
});
passport.deserializeUser(function(id, done) {
User.findById(id, function(err, user) {
done(err, user);
});
});
//end ofpassport functions
app.use(session({ secret: "cats",
resave: false, saveUninitialized: true }));
app.use(passport.initialize());
app.use(passport.session());
app.use(express.urlencoded({ extended: false }));
app.use(function(req, res, next) {
res.locals.currentUser = req.user;
next();
});
I then called the controller from the routes.js to authenticate the user yet it keeps failing and defaulting on the failredirecting
app.post('/signin', passport.authenticate("local",{
successRedirect:"/",
failureRedirect:'/signup'}))
By default, LocalStrategy expects to find credentials in parameters named username and password. If your site prefers to name these fields differently, options are available to change the defaults.
name of parameters in req.body should match with custom fields and LocalStrategy not called when there are empty fields usernameField and passwordField
const customFields = {
usernameField : "email",
passwordField : "password"
}
passport.use(
new LocalStrategy(customFields ,(username, password, done) => {
User.findOne({ username: username }, (err, user) => {
console.log(user)
if (err) {
return done(err);
};
if (!user) {
return done(null, false, { msg: "Incorrect username" });
}
if (user.password !== password) {
return done(null, false, { msg: "Incorrect password" });
}
return done(null, user);
});
})
);
passport.serializeUser(function(user, done) {
done(null, user.id);
});
passport.deserializeUser(function(id, done) {
User.findById(id, function(err, user) {
done(err, user);
});
});
//end ofpassport functions
app.use(session({ secret: "cats",
resave: false, saveUninitialized: true }));
app.use(passport.initialize());
app.use(passport.session());
app.use(express.urlencoded({ extended: false }));
app.use(function(req, res, next) {
res.locals.currentUser = req.user;
next();
});
I'm trying to assign the user to a cookie when someone logs in, but looks like passport is not assigning the data to the cookie. Below you can find the code:
app.use(bodyParser.urlencoded({
extended: true
}));
app.use(cookieParser());
app.use(bodyParser.json());
app.use(passport.initialize());
//Use session
app.use(passport.session({ secret: '=Mx;D5F}t&iJZ&w-g;FLK:%QavZgZt', cookie: { maxAge: 0 }, resave: true, saveUninitialized: true }))
app.use(express.static('server/public'));
//Set view engine
app.set('views', 'server/views')
app.set('view engine', 'pug');
//Set passport local strategy
passport.use(new LocalStrategy({ usernameField: "email" },
function (email, password, done) {
User.findOne({ 'email': email }, async function (err, user) {
console.log('user requested password caught in passport: ', password);
if (err) { return done(err); }
if (!user) {
return done(null, false, console.log('Wrong username'));
}
return await user.validatePassword(password, function (err, result) {
if (err || !result) return done(null, false, console.log('Wrong Password'));
return done(null, user);
})
});
}
));
// serialize user object
passport.serializeUser(function (user, done) {
done(null, user.id);
});
// deserialize user object
passport.deserializeUser(function (id, done) {
User.findById(id, function (err, user) {
done(err, user);
})
});
and this is the login route:
//Route for user login
app.post('/auth/local/signin',
function (req, res, next) {
passport.authenticate('local', function (err, user, info) {
console.log(err);
console.log(user);
if (err) {
console.log('passport.authenticate: error')
} else if (!user) {
console.log('passport.authenticate: user')
} else {
console.log('next handler')
console.log('Cookie assigned: ' + req.user)
return res.redirect('/dashboard')
}
return res.redirect('/login')
})(req, res, next)
}
)
As you can see, I have tried to log req.user which is giving me back undefined.
However, the console.log(user) gives me back the user from the DB, which is what I want.
Hello SO wonderful users
I am having trouble with passport js since two days and cant figure it out.
Passport Strategy is not being called.
the console.log is not being called!
any ideas ?
here is my code
//init.js
var passport = require('passport');
var LocalStrategy = require('passport-local').Strategy;
module.exports = function(app) {
passport.use(new LocalStrategy(function(username, password, done) {
console.log(username, password);
return done(null, {username: 'agent'});
}));
passport.serializeUser(function(user, done) {
done(null, 'agent');
});
passport.deserializeUser(function(id, done) {
done(null, {username: 'agent'});
});
app.use(passport.initialize());
};
//routes.js
var passport = require('passport');
module.exports = function(app) {
app.get('/login', function(req, res) {
res.send('login');
});
app.post('/login', function(req, res, next) {
passport.authenticate('local', function(err, user, info) {
if (err) {
return next(err);
}
if (!user) {
console.log(user);
console.log('no user');
return res.redirect('/login');
}
req.logIn(user, function(err) {
if (err) {
return next(err);
}
return res.redirect('/');
});
})(req, res, next);
});
//index.js, where i call the auth
require('./src/auth/init')(app);
require('./src/auth/routes')(app);
edit
solution
the issue was with postman, I hade to change the body post data to x-www-form-urlencoded
I am trying to authenticate user, using google authentication passport-google but it keeps sending InternalOAuthError: Failed to obtain request token.
error view
InternalOAuthError: Failed to obtain request token at
Strategy.OAuthStrategy._createOAuthError
(/Users/menaka/WebstormProjects/cardCreaterServer/node_modules/passport-oauth1/lib/strategy.js:396:17)
at
/Users/menaka/WebstormProjects/cardCreaterServer/node_modules/passport-oauth1/lib/strategy.js:244:41
at
/Users/menaka/WebstormProjects/cardCreaterServer/node_modules/oauth/lib/oauth.js:543:17
at passBackControl
(/Users/menaka/WebstormProjects/cardCreaterServer/node_modules/oauth/lib/oauth.js:397:13)
at IncomingMessage.
(/Users/menaka/WebstormProjects/cardCreaterServer/node_modules/oauth/lib/oauth.js:409:9)
at emitNone (events.js:72:20) at IncomingMessage.emit
(events.js:166:7) at endReadableNT (_stream_readable.js:921:12)
at nextTickCallbackWith2Args (node.js:442:9) at
process._tickCallback (node.js:356:17)
I have already enabled Google + api inside the google API Manager platform.and here is my
Authorized JavaScript origins
http://localhost:3000
and
Authorized redirect URIs
http://localhost:3000/auth/google/callback
in side my routes.js file
var User = require('./models/user');
module.exports = function(app, passport){
app.get('/', function(req, res){
res.render('index.ejs');
});
app.get('/login', function(req, res){
res.render('login.ejs', { message: req.flash('loginMessage') });
});
app.post('/login', passport.authenticate('local-login', {
successRedirect: '/profile',
failureRedirect: '/login',
failureFlash: true
}));
app.get('/signup', function(req, res){
res.render('signup.ejs', { message: req.flash('signupMessage') });
});
app.post('/signup', passport.authenticate('local-signup', {
successRedirect: '/',
failureRedirect: '/signup',
failureFlash: true
}));
app.get('/profile', isLoggedIn, function(req, res){
res.render('profile.ejs', { user: req.user });
});
app.get('/auth/google', passport.authenticate('google', {scope: ['profile','email']}));
app.get('/auth/google/callback',
passport.authenticate('google', { successRedirect: '/profile',
failureRedirect: '/' }));
app.get('/logout', function(req, res){
req.logout();
res.redirect('/');
})
};
function isLoggedIn(req, res, next) {
if(req.isAuthenticated()){
return next();
}
res.redirect('/login');
}
inside my passport.js
var LocalStrategy = require('passport-local').Strategy;
var GoogleStrategy = require('passport-google-oauth').OAuthStrategy;
var User = require('../app/models/user');
var configAuth=require('./auth');
module.exports = function(passport) {
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){
process.nextTick(function(){
User.findOne({'local.username': email}, function(err, user){
if(err)
return done(err);
if(user){
return done(null, false, req.flash('signupMessage', 'That email already taken'));
} else {
var newUser = new User();
newUser.local.username = email;
newUser.local.password = newUser.generateHash(password);
newUser.save(function(err){
if(err)
throw err;
return done(null, newUser);
})
}
})
});
}));
passport.use('local-login', new LocalStrategy({
usernameField: 'email',
passwordField: 'password',
passReqToCallback: true
},
function(req, email, password, done){
process.nextTick(function(){
User.findOne({ 'local.username': 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', 'invalid password'));
}
return done(null, user);
});
});
}
));
passport.use(new GoogleStrategy({
consumerKey: configAuth.GoogleAuth.clientID,
consumerSecret: configAuth.GoogleAuth.clientSecret,
callbackURL: configAuth.GoogleAuth.callbackURL
},
function(accessToken, refreshToken, profile, done) {
process.nextTick(function(){
User.findOne({'google.id':profile.id},function(err,user){
if(err){
return done(err);
}
if(user){
return done(null,user);
}else{
var newUser=new User();
newUser.google.id=profile.id;
newUser.google.token=accessToken;
newUser.google.name=profile.displayName;
newUser.google.email=profile.emails[0].value;
newUser.save(function(err){
if(err){
throw err;
}
return done(null,newUser);
})
}
});
});
}
));
};
the callbackURL is
http://localhost:3000/auth/google/callback
what do i have to do in order to fix this issue ?
Banged my head on this for awhile - seems like there's an old link reference in the basic strategy. Recommend you try
https://github.com/jaredhanson/passport-google-oauth2
instead. It's up-to-date and worked immediately for me!
*The debug solution got me to this solve, btw.