anonymousfox
anonymousfox

Reputation: 809

Facebook OAuth creates new user each time using Passport and Express

I am using the Passport node module in conjunction with Express to enable users to login via Facebook, Twitter, and Google. I have setup Facebook and Twitter so far and users can login successfully, but it creates a new user every time even though I have tried to make it recognize when a user has already created an account. Here is the code I am using:

passport.use(new FacebookStrategy({
        clientID: '********************',
        clientSecret: '***********************',
        callbackURL: "http://www.wundertutor.com:3000/auth/facebook/callback"
    }, function(accessToken, refreshToken, profile, done) {
        processProfile(profile, function(err, user) {
            if (err) throw err;
            done(null, user);
        });
    }));
function processProfile(profile, callback) {
        if (profile.emails) {
            profile.emails.forEach(function(email) {
                findUserByEmail(email.value, function(err, user) {
                    if (user) {
                        return callback(null, user);
                    }
                });
            });
            var newUser = {
                id: profile.id,
                firstName: profile.name.givenName,
                lastName: profile.name.familyName,
                email: profile.emails[0].value
            };
            user.create(newUser, profile.provider, function(err, user) {
                if (err) throw err;
                return callback(null, user);
            });
        }
    }


    function findUserByID(id, callback) {
        pool.getConnection(function(err, connection) {
            var query = connection.query("SELECT * FROM users WHERE id = ?", id, function(err, rows) {
                connection.end();
                var user;
                if (rows.length == 1) {
                    user = {
                        id: rows[0].id,
                        role: rows[0].role,
                        firstName: rows[0].firstName,
                        lastName: rows[0].lastName,
                        email: rows[0].email
                    };
                }
                return callback(null, user);
            });
        });
    }


    function findUserByEmail(email, callback) {
        if (email) {
            pool.getConnection(function(err, connection) {
                if (err) throw err;
                var query = connection.query('SELECT * FROM users WHERE email = ?', email, function(err, rows) {
                    connection.end();
                    if (err) throw err;
                    if (rows.length == 1) {
                        console.log("C");
                        return callback(null, rows[0]);
                    } else {
                        return callback(null, null);
                    }
                });
            });
        } else {
            return callback(null, null);
        }
    }

    passport.serializeUser(function(user, done) {
        done(null, user.id);
    });

    passport.deserializeUser(function(id, done) {
        findUserByID(id, function(err, user) {
            done(null, user);
        });
    });

In processProfile, I have it loop through each email associated with a user profile and check to see whether that user is already in our database. If they are, then it gets that user's info and passes it to the 'done' callback to be serialized and log the user in. The strange thing is that when a user who is already in our database is logged in, it does get to this part of the code and returns the user successfully (determined by a series of console.logs), but for some reason it still creates a new user in the database each time they try to log in.

Also, on a side note, when I log in normally (via username and password), I am redirected to our learn page '/learn', but when I log in via Facebook, I am redirected to the learn page with some extra stuff afterwards '/learn#='. Any ideas?

Upvotes: 0

Views: 431

Answers (1)

rawbee
rawbee

Reputation: 3008

Try rewriting your processProfile function to something like this:

function processProfile(profile, callback) {
        var result;
        if (profile.emails) {
            profile.emails.forEach(function(email) {
                findUserByEmail(email.value, function(err, user) {
                    if (user) {
                        result = user;
                    }
                });
            });
            if( !user ) {
               var newUser = {
                   id: profile.id,
                   firstName: profile.name.givenName,
                   lastName: profile.name.familyName,
                   email: profile.emails[0].value
               };
               user.create(newUser, profile.provider, function(err, user) {
                   if (err) throw err;
                   result = user;
                   callback( null, result );
               });
            } else {
                callback( null, result );
            }
        }
    }

Upvotes: 1

Related Questions