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
、ユーザー プロファイルに関連付けられた各電子メールをループして、そのユーザーが既にデータベースに存在するかどうかを確認します。そうであれば、そのユーザーの情報を取得し、それを 'done' コールバックに渡してシリアル化し、ユーザーをログインさせます。奇妙なことに、データベースに既に存在するユーザーがログインすると、コードのこの部分は正常にユーザーを返します (一連の console.logs によって決定されます) が、何らかの理由で、ログインを試行するたびにデータベースに新しいユーザーが作成されます。
また、補足として、通常 (ユーザー名とパスワードを使用して) ログインすると、学習ページ '/learn' にリダイレクトされますが、Facebook 経由でログインすると、学習ページにリダイレクトされ、いくつかの追加情報が表示されます。その後 '/learn# = '. 何か案は?