NodeJS Passport:通过两种策略进行多重登录 - 序列化问题

时间:2013-02-19 21:41:04

标签: node.js authentication passport.js

我想为用户提供以两种策略之一登录的能力:通过Instagram和通常的本地策略。对于本地我已经编写了简单的函数来在DB中查找用户并提供它的用户信息。这是它的工作原理:

passport.use(new InstagramStrategy({
    clientID: global.INSTAGRAM_CLIENT_ID,
    clientSecret: global.INSTAGRAM_CLIENT_SECRET,
    callbackURL: "http://**.**.**.**:3000/auth/instagram/callback"
  },
  function(accessToken, refreshToken, profile, done) {
    process.nextTick(function () {
        console.log('Access token: ' + accessToken);
        global.access_token = accessToken;
      return done(null, profile);
    });
  }
));

passport.use(new LocalStrategy(
    function(email, password, done) {
    console.log('chec user');
    process.nextTick(function() {
        db.findByEmail(email, function(err, user) {
            if (!user) {
                console.log('Unknown user ' + email);
                return done(null, false, {
                    message: 'Unknown user ' + email
                });
            }
            if (user.password != crypt.getMD5fromString(password)) {
                console.log('Invalid password');
                return done(null, false, {
                    message: 'Invalid password'
                });
            }
            return done(null, user);
        })
    });
}));

但是我的自定义序列化和deSerialize函数不适用于Instagram策略:

    /* THESE FUNCTIONS WORK WITH INSTAGRAM STRATEGY
passport.serializeUser(function(user, done) {
  done(null, user);
});

passport.deserializeUser(function(obj, done) {
  done(null, obj);
});*/

    /*THESE ARE FOR LOCAL STRATEGY*/
passport.serializeUser(function(user, done) {done(null, user._id);});
passport.deserializeUser(function(id, done) {db.findById(id, function(err, user) {done(err, user);});});

如何避免这个错误?我的目标 - 提供登录Instagram,并在成功登录检查后 - 如果用户有本地帐户(通过电子邮件或Instagram昵称),从数据库获取数据。虽然用户应该能够通过本地策略在没有Instagram的情况下登录。感谢。

1 个答案:

答案 0 :(得分:4)

简短的回答是:对本地和第三方验证回调使用相同的用户对象类型。您可能希望在Instagram验证回调中进行设置:而不是调用done(null,profile),您可能想要创建一个新的User对象,分配myUser.instagram = profile和回调done(null, myUser)或类似的东西。

我有一些示例代码,演示了设置多个身份验证系统的一种方法。您可以在此处找到它:https://github.com/therealplato/passport-multiauth-demo/blob/master/app.js

一些警告:这是为Express 2.x编写的,它以不同于3的方式处理服务器,并且具有不同的语法来发送响应。 编辑,演示代码已更新为快递3.x

此外,Google方法是Oauth 1.我无法让Oauth 1 google auth在localhost上工作,它会出错[{1}}

有趣的是,我今天花了很多时间努力让Oauth 2与我的本地用户很好地合作。所以,如果我能找时间,我会尝试更新Express 3和Oauth 2的演示代码,但没有承诺:)