I've been trying to make a login with facebook and passport.js. My local login with passport worked just fine but together they are giving me trouble. I'm working with express, mongoose , passport and passport-facebook.
I've tried a number of things to fix it (so many that I forgot most of them) I'm just very lost now
I keep getting this error in my shell:
GET /auth/facebook 302 4.876 ms - 0
{ _id: 5918a12f6ab8492354a3098c,
facebook:
{ email: '[email protected]',
name: 'John',
token: 'EAABhTCea34sBAMkmOVWU0G62WUc3aNihjtWOdJDSD0XS9NwPPBXZChCTXEmeYe8xp0P5vT8WY0ZBaDwKUWojB96Bz661D9ZCZBxSKx8tfZBBmD3HycoqgsJxZAQykp358xJxoCU1TgUOViZB9JVzmP935r5bFQCoLOoEeZCTzEinvxMO8dqo8DzX',
id: '10155442104714916' } }
(node:9044) DeprecationWarning: Mongoose: mpromise (mongoose's default promise library) is deprecated, plug in your own promise library instead: http://mongoosejs.com/docs/promises.html
events.js:165
throw err;
^
Error: Uncaught, unspecified "error" event. (null)
at Function.emit (events.js:163:17)
at E:\Documenten\GitHub\webtech2-demoordie\node_modules\mongoose\lib\model.js:3739:13
at E:\Documenten\GitHub\webtech2-demoordie\node_modules\mongoose\lib\services\model\applyHooks.js:146:20
at _combinedTickCallback (internal/process/next_tick.js:73:7)
at process._tickCallback (internal/process/next_tick.js:104:9)
I've tried several things to fix it but can't put my finger on what the trouble is . Any help is much appreciated , when I close my connection and reconnect my user is in the mongo database but that's not how it should work.
var express = require('express');
var router = express.Router();
var passport = require('passport');
var expressvalidator = require('express-validator');
var mongoose = require('mongoose');
var schema = mongoose.Schema;
var users = require('../models/users');
//mongoose.connect('localhost:27017/DemoOrDIe');
/* GET home page. */
router.get('/', function(req, res, next) {
res.render('index.pug', { title: 'Demo Or Die' });
});
router.get('/login',function(req, res, next) {
res.render('login.pug', {message : req.flash('loginMessage') });
});
router.get('/signup', function(req, res) {
res.render('signup.pug', { message: req.flash('signupMessage')/*,success: req.session.success, errors: req.session.errors */});
});
router.get('/profile', /*isLoggedIn,*/ function(req, res) {
res.render('profile.pug', { user: req.user });
});
router.get('/logout', function(req, res) {
req.logout();
res.redirect('/');
});
router.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
}));
/*router.post('/signup',function(req,res){
var newUser = new users({
name: req.body.name,
email: req.body.email,
password: req.body.password
});
newUser.save(function (err,error,users) {
req.checkBody("email", "Enter a valid email address.").isEmail();
req.checkBody("email", "You must enter an email").notEmpty();
req.checkBody("name","you must enter a name.").notEmpty();
req.checkBody("password", "You must enter a password").notEmpty();
var errors = req.validationErrors();
if (errors) {
res.render('signup', { errors: errors });
return;
} else {
res.send(users);
}
});
});*/
router.post('/login', passport.authenticate(['local-login'], {
successRedirect: '/profile',
failureRedirect: '/login',
failureFlash : true
}));
// FACEBOOK ROUTES
// route for facebook authentication and login
router.get('/auth/facebook', passport.authenticate(['facebook'], { scope : ['email'] }));
// handle the callback after facebook has authenticated the user
router.get('/auth/facebook/callback',
passport.authenticate('facebook', {
successRedirect : '/profile',
failureRedirect : '/'
}));
module.exports = router;
function isLoggedIn(req, res, next) {
if (req.isAuthenticated())
return next();
res.redirect('/');
}
var mongoose = require('mongoose');
var expressvalidator = require('express-validator');
var bcrypt = require('bcrypt-nodejs');
var userSchema = mongoose.Schema({
local:{
email: String,
/* name: { type: String,
required: true
},*/
password: String
},
facebook : {
id :String,
token : String,
email : String,
name : String
}
}, {
collection: 'DemoOrDie'
});
// generating a hash
userSchema.methods.generateHash = function(password) {
return bcrypt.hashSync(password, bcrypt.genSaltSync(8), null);
};
// checking if password is valid
userSchema.methods.validPassword = function(password) {
return bcrypt.compareSync(password, this.local.password);
};
module.exports = mongoose.model('User', userSchema);
var LocalStrategy = require('passport-local').Strategy;
var User = require('../models/users.js');
var FacebookStrategy = require('passport-facebook').Strategy;
// load the auth variables
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);
});
});
// FACEBOOK
passport.use('facebook' ,new FacebookStrategy({
// pull in our app id and secret from our auth.js file
clientID : configAuth.facebookAuth.clientID,
clientSecret : configAuth.facebookAuth.clientSecret,
callbackURL : configAuth.facebookAuth.callbackURL,
profileFields: ["id","emails", "displayName"]
},
// facebook will send back the token and profile
function(token, refreshToken, profile, done) {
// asynchronous
process.nextTick(function() {
// find the user in the database based on their facebook id
User.findOne({ 'facebook.id' : profile.id }, function(err, user) {
// if there is an error, stop everything and return that
// ie an error connecting to the database
if (err)
return done(err);
// if the user is found, then log them in
if (user) {
return done(null, user); // user found, return that user
} else {
// if there is no user found with that facebook id, create them
var newUser = new User();
// set all of the facebook information in our user model
newUser.facebook.id = profile.id; // set the users facebook id
newUser.facebook.token = token; // we will save the token that facebook provides to the user
newUser.facebook.name = profile.displayName; // look at the passport user profile to see how names are returned
newUser.facebook.email = profile.emails[0].value; // facebook can return multiple emails so we'll take the first
console.log(newUser);
// save our user to the database
newUser.save(function(err) {
if (err)
console.log(err);
throw err;
// if successful, return the new user
return done(null, newUser);
});
}
});
});
}));
//LOCAL
passport.use('local-signup', new LocalStrategy({
usernameField: 'email',
passwordField: 'password',
passReqToCallback: true
},
function(req, email, password, done) {
process.nextTick(function() {
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);
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) {
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', 'Wrong password.'));
return done(null, user);
});
}));
};
When you trying to save the New user in the Facebook strategy you are always throwing an error.
newUser.save(function(err, user){
If(err) {
console.log(err)
throw err
// return done (err)
}
return done(null, user)
})
Seems to be Just the '{}'. You forgot.
Hope It help you.