passport google auth: connect-flash not working - node.js

I'm trying to flash a message when someone try to login with gmail but gmail is not found in database.... everything works fine but if there is no gmail account in database then it should return a flash message but flash not work! I've searched a lot on this topic but everyone post about passport-local...
here is my code:
--middlewares
app.use(session({
resave: false,
saveUninitialized: true,
secret: "a87ds34cN5070AS%ASasyasaad"
}));
app.use(flash());
app.use(passport.initialize());
app.use(passport.session());
--passport codes
passport.serializeUser(function(user, done) {
done(null, user);
});
passport.deserializeUser(function(user, done) {
done(null, user);
});
passport.use(new GoogleStrategy({
clientID: process.env.GOOGLE_CLIENT_ID,
clientSecret: process.env.GOOGLE_CLIENT_SECRET,
callbackURL: process.env.GOOGLE_CALLBACK_URI
},
function(req, accessToken, refreshToken, profile, cb){
// check if this email exist on database
db.get("SELECT * FROM users WHERE gmail=?", [profile._json.email], (error, user) => {
if(error){
console.log("there is an error!");
return cb(error, false);
}
if(user){
/* if the email is exist but user fullname field is empty then retrive these data and update this user */
if(profile.displayName != user.full_name){
db.run("UPDATE users SET full_name=? WHERE gmail=?", [profile.displayName, user.gmail], (error, done) => {
if(error){
console.log("fname error: "+error);
}
});
}
/* if the email is exist but profile avatar is empty then retrive profile avatar url from gmail and update this user */
if(profile._json.picture.split("=")[0] != user.picture){
const profile_pic = profile._json.picture.split("=")[0];
db.run("UPDATE users SET picture=? WHERE gmail=?", [profile_pic, user.gmail], (error, done) => {
if(error){
console.log("picture error: "+error);
}
});
}
return cb(error, user);
}else{
// if the email isn't exist then show this flash msg
return cb(null, false, req.flash("flash_msg", "You don't have any permission to access this area!"));
}
});
}
));
--login & callback route
app.get("/login", (req, res) => {
res.render("login.html");
});
app.get("/auth/google", passport.authenticate('google', {scope: ['profile', 'email']}));
app.get("/auth/google/callback",
passport.authenticate('google', {
successRedirect: "/",
failureRedirect: '/login',
successFlash: true,
failureFlash: true
}),
function(req, res) {
res.redirect("/");
});

Related

Facebook strategy with sapper and polka

I need to make a connection with polka (not Express) and using a passport-facebook strategy. On my serverjs:
var app = polka();
passport.serializeUser(function(user, cb){
return cb(null, profile);
});
passport.deserializeUser(function(obj, cb){
return cb(null, obj);
});
passport.use(new Strategy({
clientID: *****,
clientSecret: '******',
callbackURL: 'http://localhost:3000/login/facebook/callback',
//campo opzionale, specifico gli oggetti del profilo che voglio tornato
profile: ['id', 'displayName']
},
function(accessToken, refreshToken, profile, done) {
//Check the DB to find a User with the profile.id
User.findOne({ uid: profile.id }, function(err, user) {
if(err) {
console.log(err); // handle errors!
}
if (user) {
console.log("find user!", user);
done(null, user); //Login if User already exists
} else { //else create a new User
user = new User({
uid: profile.id, //pass in the id and displayName params from Facebook
name: profile.displayName
});
user.save(function(err) { //Save User if there are no errors else redirect to login.
if(err) {
console.log(err); // handle errors!
} else {
console.log("saving user ...");
done(null, user);
console.log("user", user);
}
});
}
});
}
));
app
//va sempre messo prima di passport.session
.use(require('express-session')({ secret: 'keyboard cat', resave: true, saveUninitialized: true }))
.use(passport.initialize())
.use(passport.session())
//definisco le rotte
//rotta di login
.get('/login/facebook',
passport.authenticate('facebook')
)
//callback
.get('/login/facebook/callback',
//da confermare se รจ supportato il fialureRedirect
//passport.authenticate('facebook', {failureRedirect: '/'}),
passport.authenticate('facebook', {failureRedirect: '/'}),
function(req, res){
res.writeHead(302, {
'Location': '/admin/menu',
'content-type': 'document'
});
res.end();
}
)
.use(
compression({ threshold: 0 }),
sirv('static', { dev }),
formData.parse(options),
formData.format(),
//formData.stream(),
formData.union(),
json(),
sapper.middleware()
)
When i make the login the console shows also that i'm already logged in (it created also a object on the mongodbclient and it's also finded), but the problem is that redirect me on some url with
http://localhost:3000/login/facebook/callback?code=AQBBJIV61HxahPCtWBgMR23OMpU8MXfxDcD3BeRDTUw2rK5FvTnXq5n...
with a message "profile is not defined"
and on the console i have this on pending
On serializeUser you return profile that is never declared you have to use:
passport.serializeUser(function(user, cb){
return cb(null, user);
});

Github oAuth with PassportJS not authenticated

I'm trying to use passportJS to authenticate with the github-strategy. I've previously used passportJS with success, but not with the github-strategy, though I don't figure it should be much different. /viewData is the route in which I'm testing for authentication.
The strategy authenticates successfully and puts the data in the DB and when I serialize and deserialize the user data is in fact there. The problem comes when I try to check in any route after if the req.isAuthenticated() or even if req.session.passport.user exists and it returns false and undefined respectively. The weird thing the same check in app.js after I've redirected through /testAuth the authentication logs correctly with the true and id#. So I feel like its some issue with express-session or the passport integration with that that's breaking it, but I can't find it. I've been on this for a long time so hopefully someone can help me.
app.use(cookieParser('test'));
app.use(session({
secret: 'test',
resave: false,
saveUninitialized: true
}));
//pasport setup
app.use(passport.initialize());
app.use(passport.session());
// Passport init
passport.use(new GithubStrategy({
clientID: config.github.clientID,
clientSecret: config.github.clientSecret,
callbackURL: config.github.callbackURL },
function(accessToken, refreshToken, profile, done) {
User.findOne({ oauthID: profile.id }, function(err, user) {
if(err) {
console.log(err); // handle errors!
}
if (!err && user !== null) {
done(null, user);
} else {
user = new User({
oauthID: profile.id,
name: profile.displayName,
created: Date.now()
});
user.save(function(err) {
if(err) {
console.log(err); // handle errors!
} else {
console.log("saving user ...");
done(null, user);
}
});
}
});
}
));
// test authentication
function ensureAuthenticated(req, res, next) {
if (req.isAuthenticated()) { return next(); }
console.log("Not Authenticated", req.user);
res.redirect('/');
}
app.get('/testAuth', ensureAuthenticated, function(req, res){
User.findById(req.session.passport.user, function(err, user) {
if(err) {
console.log(err); // handle errors
} else {
res.redirect('/viewData');
}
});
});
//auth pages
app.get('/auth/github',
passport.authenticate('github'),
function(req, res){});
app.get('/auth/github/callback',
passport.authenticate('github', { failureRedirect: '/' }),
function(req, res) {
res.redirect('/testAuth');
});
// serialize and deserialize for session
passport.serializeUser(function(user, done) {
console.log('serializeUser: ' + user);
done(null, user._id);
});
passport.deserializeUser(function(id, done) {
User.findById(id, function(err, user){
console.log('deserializeUser: ' + user);
if(!err) done(null, user);
else done(err, null);
});
});
So this is a weird one, but I was fixing something else that was weird and in doing so solved this problem. I just moved my
app.use('/', index);
app.use('/viewData', viewData);
To below all the passport code and it works now.

Passport req.isAuthenticated() doesn't work

I'm using express-session and passport to authenticate.
Here's my module :
(updated)
passport.use(new LocalStrategy(
function(username, password, done) {
LamAdmin.findOne({ email: username }, function (err, user) {
if (err) { return done(err); }
if (!user) { return done(null, false, { message: 'Incorrect username' }); }
if (!comparePassword(user.password, password)) { return done(null, false, { message: 'Incorrect password' }); }
return done(null, user);
});
}
));
router.post('/login', passport.authenticate('local',{
successRedirect: '/p/dashboard',
failureRedirect: '/p',
failureFlash: true
}));
passport.serializeUser(function(user, done) {
done(null, user.id);
});
passport.deserializeUser(function(id, done) {
LamAdmin.findById(id, function (err, user) {
done(err, user);
});
});
function checkAuth(req,res,next) {
if (req.isAuthenticated()) {
next();
} else {
res.redirect('/p');
}
}
// //DOES NOT WORK WITH CHECKAUTH MIDDLEWARE
// router.get('/dashboard',(req,res,next)=> {
// res.render('dashboard');
// });
router.get('/dashboard',checkAuth,(req,res,next)=> {
res.render('dashboard');
});
checkAuth is my middleware and idk why it always returns false.
This is passport and session configs in app.js :
//sessions
app.use(session({
secret: 'secret',
saveUninitialized: true,
resave: true,
cookie: { secure: false } // Remember to set this
}));
//passport
app.use(passport.initialize());
app.use(passport.session());
Is there anything wrong with my checkAuth middleware ?
Or my redirect to Dashboard view?
Thanks in advance!
When you call passport.authenticate() method, it uses a strategy to authenticate the user. If you have the user information stored in a local DB, then you can use the Local Strategy that will use username and password to authenticate. So in your app.js add the following:
const LocalStrategy = require('passport-local').Strategy;
passport.use(new LocalStrategy(
function(username, password, done) {
/* Change this to fetch user info from your db
User.findOne({ username: username }, function (err, user) {
if (err) { return done(err); }
if (!user) { return done(null, false); }
if (!comparePasswords(user.password, password)) { return done(null, false); }
return done(null, user);
});
*/
}
));
When the user is authenticated, serializeUser() method is called with the user object returned from the above method passed as an argument and express appends the value returned to the current user session in req.session.passport.user
passport.serializeUser(function(user, done) {
done(null, user.id);
});
On each subsequent request, when isAuthenticated() method is called, passport checks if some value is present in req.session.passport.user. If user information is present, it calls the deserializeUser() method which appends the user information to the request and can be accessed via req.user
passport.deserializeUser(function(id, done) {
// Replace it with your db
User.findById(id, function (err, user) {
done(err, user);
});
});

passport.js 'user' is undefined when sucessRedirect

Please, I'm trying to redirect to the "edit user route" page after login but the req.user._id is showing undefined, any idea what's wrong here?
login router
router.post('/login', (req, res, next) => {
passport.authenticate('local', {
successRedirect:'../profiles/edit/' + req.user._id, <<<< **UNDEFINED**
failureRedirect:'./login',
failureFlash: true,
})(req, res, next);
});
passport.js
module.exports = function(passport) {
passport.use(new LocalStrategy({
},
(username, password, done) => {
Profile.findOne({
username:username
}).then(user => {
if(!user) {
return done(null, false, {message: 'No user found'});
}
bcrypt.compare(password, user.password, (err, isMatch) => {
if (err) throw err;
if (isMatch) {
return done(null, user);
} else {
return done(null, false, {message: 'Password Incorrect'});
}
})
})
}
));
passport.serializeUser(function(user, done) {
done(null, user.id);
});
passport.deserializeUser(function(id, done) {
Profile.findById(id, function(err, user) {
done(err, user);
});
});
}
app.js
app.use(session({
secret: 'secret',
resave: true,
saveUninitialized: true,
}));
app.use(passport.initialize());
app.use(passport.session());
I'm getting:
TypeError: Cannot read property '_id' of undefined
You can't get user details in the authenticate method, it will check if username has been found and then pass it to the next middleware
app.post('/login',
passport.authenticate('local', { failureRedirect: '/login' }),
function(req, res) {
// here you can access user info
res.redirect('../profiles/edit/' + req.user._id);
});

MEAN stack auth with passport: login not working (but I can create new user)

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

Resources