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();
});
Related
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.
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
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.
I have some trouble implementing passport-local on my NodeJS application. I don't understand what I'm doing wrong here. I'll list the important code for this question here.
app.js:
var passport = require('passport');
var LocalStrategy = require('passport-local').Strategy;
var bodyParser = require('body-parser');
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.use(passport.initialize());
app.use(passport.session());
users.js:
var express = require('express');
var router = express.Router();
var passport = require('passport');
var LocalStrategy = require('passport-local').Strategy;
var User = require('../models/user.js');
passport.serializeUser(function(user, done) {
done(null, user.id);
});
passport.deserializeUser(function(id, done) {
User.getUserById(id, function(err, user) {
done(err, user);
});
});
passport.use(new LocalStrategy(
function(username, password, done) {
console.log('Entered passport'); // This doesn't even happen
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);
}
console.log('Invalid Password');
return done(null, false, {
message: 'Invalid Password'
});
});
return done(null, user);
});
}
));
router.post('/login', passport.authenticate('local', {
successRedirect: '/',
failureRedirect: '/users/login',
failureFlash: 'Invalid username or password'
}), function(req, res) {
console.log("Authentication Successfull!");
req.flash('success', 'You are logged in');
res.redirect('/');
});
user.js (Model):
module.exports.getUserByUsername = function(username, callback) {
var query = { username: username };
User.findOne(query, callback);
}
module.exports.getUserById = function(id, callback) {
User.findById(id, callback);
}
module.exports.comparePassword = function(candidatePassword, hash, callback) {
bcrypt.compare(candidatePassword, hash, function(err, isMatch) {
if(err) return callback(err);
callback(null, isMatch);
});
}
I'm not getting any syntax errors. In users.js I want to log a message to the console, but it doesn't even get there. The post function on the login gets fired when I just enter a function with a console.log there, but now it seems that it doesn't. It just reloads the page (looks like it). Any help is appreciated.
try to mount session middleware before passport initilized:
var session = require('express-session')
app.use(session({ secret: 'xxxxxxx' }));
app.use(passport.initialize());
app.use(passport.session());
I have an express app that I am trying to authenticate with passport-local. Here is my express app:
app.use(express.bodyParser());
app.use(express.cookieParser());
app.use(express.session({ secret: 'this is a string' }));
app.use(passport.initialize());
app.use(passport.session());
client = new pg.Client(connectionString);
client.connect();
passport.use(new LocalStrategy(
function(username, password, done) {
var query = client.query('SELECT * FROM users WHERE EMAIL = $1', [username], function(err, result){
if(err) {
console.log("Error");
return done(err);
}
if(!result.rows.length > 0) {
console.log("No users");
return done(null, false, { message: 'User not found'});
}
if(result.rows[0].password !== password) {
console.log("incorrect password");
return done(null, false, { message: 'Password Incorrect'});
}
console.log('authenticated');
return done(null, result.rows[0]);
});
}
));
passport.serializeUser(function(user, done) {
'use strict';
console.log('serialize');
console.log(user);
done(null, user.email);
});
passport.deserializeUser(function(id, done) {
'use strict';
console.log('deserialize');
User.findById(id, function(err, user) {
done(err, user);
});
});
app.post('/login', passport.authenticate('local'), function(req, res) {
'use strict';
console.log(req.user.username);
});
app.listen(port, function() {
'use strict';
console.log('Listening on:', port);
});
I then hit the /login url with this json in my body: {username: 'jason#gmail.com', password: 'password }. I go through the LocalStrategy function and then in the serialize function it makes it to the done function and then just hangs. I get no errors or additional logging, the connection just stays open and control is not given back to the caller. I never receive a http status, it just hangs.
I think it is a problem with my session, but I do not understand what to do next?
Ok, could you try a redirect there? It looks like your session / auth is ok, if you get a proper username at that point.
app.post('/login', passport.authenticate('local', {
successRedirect: '/somewhere_intern',
failureRedirect: '/login'
}));