我将 Passport 节点模块与 Express 结合使用,以使用户能够通过 Facebook、Twitter 和 Google 登录。到目前为止,我已经设置了 Facebook 和 Twitter,并且用户可以成功登录,但它每次都会创建一个新用户,即使我试图让它识别用户何时已经创建了一个帐户。这是我正在使用的代码:
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);
});
});
在processProfile
中,我让它遍历与用户配置文件关联的每封电子邮件,并检查该用户是否已经在我们的数据库中。如果是,那么它会获取该用户的信息并将其传递给“完成”回调以进行序列化并让用户登录。奇怪的是,当已经在我们数据库中的用户登录时,它确实会到达这部分代码并成功返回用户(由一系列console.logs确定),但由于某种原因,每次尝试登录时它仍会在数据库中创建一个新用户。
另外,附带说明一下,当我正常登录时(通过用户名和密码),我会被重定向到我们的学习页面“/learn”,但是当我通过 Facebook 登录时,我会被重定向到包含一些额外内容的学习页面之后'/learn# = '。有任何想法吗?