使用护照登录社交日志用户到同一帐户

时间:2018-01-05 14:40:25

标签: node.js mongodb passport-local passport-facebook passport-google-oauth2

我尝试使用社交媒体(FB和Google)以及本地策略实施登录。我有护照本地工作正常(除了允许重复的电子邮件,但单独的问题)但我看到Facebook和谷歌策略的一些奇怪的行为。这是一个场景:

  1. 使用Facebook或Google登录
  2. 退出
  3. 以初始登录的相反方式登录(即第一个FB,第二个Google)
  4. 该应用使用初始帐户而不是第二个帐户登录。
  5. 我按照本页面上的教程设置了各种策略

    http://mherman.org/blog/2013/11/10/social-authentication-with-passport-dot-js/#.Wk93wN-nFPb

    策略示例:

    
    
    passport.use(new googleStrategy({
        clientID: config.google.clientID,
        clientSecret: config.google.clientSecret,
        callbackURL: config.google.callbackURL,
        scope: ['profile', 'email'],
        passReqToCallback: true
    },
        (request, accessToken, refreshToken, profile, done) => {
    
            var emailArray = new Array();
    
            profile.emails.forEach((email) => {
                emailArray.push(email.value);
            })
    
            User.findOne({ $or: [{ oauthID: profile.id }, { email: { $in: [emailArray] } }] }, (err, user) => {
                if (err) {
                    console.log(err);
                }
                if (!err && user !== null) {
                    console.log('Already existing user:' + user);
                    done(null, user);
    
                } else {
                    console.log('Creating a new user');
                    user = new User({
                        email: emailArray[0],
                        username: profile.name.givenName,
                        oauthID: profile.id
                    });
                    user.save(function (err) {
                        if (err) {
                            console.log(err);
                        } else {
                            done(null, user);
                        }
                    });
                }
            });
        }
    ));
    
    passport.serializeUser(User.serializeUser());
    passport.deserializeUser(User.deserializeUser());
    
    
    

    User MongoDB模型

    
    
    var mongoose = require('mongoose'),
        passportLocalMongoose = require('passport-local-mongoose');
    
    var userSchema = new mongoose.Schema({
        email: String,
        username: String,
        password: String,
        oauthID: Number
    });
    
    userSchema.plugin(passportLocalMongoose);
    
    module.exports = mongoose.model('User', userSchema);
    
    
    

    auth路由

    
    
    router.get('/auth/google',
        passport.authenticate('google'), (req, res) => {
            console.log('Authenticating as: ' + req.user.email + ', oAuthID: ' + req.user.oauthID);
        });
    
    router.get('/auth/google/callback',
        passport.authenticate('google', { failureRedirect: '/auth' }), (req, res) => {
            console.log('Authenticated as: ' + req.user.email + ', oAuthID: ' + req.user.oauthID);
            res.redirect('/');
        });
    
    
    

    Facebook战略基本相同。

    我的第一个想法是User.findOne()查询不正确,但如果我将查询输入Mongo控制台,我会收到预期的结果。

    接下来,我将登录设置为查看req.user在身份验证过程中各个点的值。除了最终登录到他们最初登录的帐户外,每一步看起来都很正常。

    所以我不确定问题出在哪里......我对网络开发很陌生,所以非常感谢任何帮助/解释。

1 个答案:

答案 0 :(得分:1)

我找到的解决方案......

当我最初设置护照本地模块时,我创建了passport.serializeUser()passport.deserializeUser()方法,如下所示:



passport.serializeUser(User.serializeUser());
passport.deserializeUser(User.deserializeUser());




使用了static passport-local-mongoose序列化和反序列化方法。

将这些更改为以下功能可以解决使用FB或Google策略的问题,并且不会影响本地策略



passport.serializeUser((user, done) => {

    return done(null, user._id);

});

passport.deserializeUser((id, done) => {

    User.findById(id, (err, user) => {
        if (!err) {
            return done(null, user);
        } else {
            return done(err, null);
        }
    });

});