0

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# = '. 何か案は?

4

1 に答える 1

1

processProfile関数を次のように書き換えてみてください。

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 );
            }
        }
    }
于 2013-07-23T19:28:57.017 に答える