【问题标题】:How to implements two strategies with passportjs如何用passportjs实现两种策略
【发布时间】:2015-01-07 19:21:13
【问题描述】:

我的 node/express 应用中有两个模型:

  1. 用户模型(简单用户认证)
  2. 经理模型(具有不同权限和不同字段的用户)

我想用护照来认证他们:

  1. 用户与一对:用户名/密码
  2. 经理与夫妇:电子邮件/密码

我为 User 模型正确实现了 PassportJS,但现在我尝试为 Manager 模型做同样的事情。

exports.postlogin = function(req, res, next) {
    passport.authenticate('user', function(err, user, info) {
        if (err) { return next(err) }
        if (!user) {
            req.session.messages =  [info.message];
            return res.redirect('/login')
        }
        req.logIn(user, function(err) {
            if (err) { return next(err); }
            return res.redirect('/');
        });
    })(req, res, next);
};

exports.postlogin = function(req, res, next) {
    passport.authenticate('manager', function(err, manager, info) {
        if (err) { return next(err) }
        if (!manager) {
            req.session.messages =  [info.message];
            return res.redirect('/manager_signup')
        }
        req.logIn(manager, function(err) {
            if (err) { return next(err); }
            return res.redirect('/');
        });
    })(req, res, next);
};

两种策略:

passport.use('user', new LocalStrategy(function(username, password, done) {
    UserModel.findOne({ username: username }, function(err, user) {
        if (err) { return done(err); }
        if (!user) { return done(null, false, { message: 'Unknown user ' + username }); }
        user.comparePassword(password, function(err, isMatch) {
            if (err) return done(err);
            if(isMatch) {
                return done(null, user);
            } else {
                return done(null, false, { message: 'Invalid password' });
            }
        });
    });
}));

passport.use('manager', new LocalStrategy({usernameField: 'manager_signin_email', passwordField: 'manager_signin_password'},function(manager_signin_email, manager_signin_password, done) {
    ManagerModel.findOne({ email: manager_signin_email }, function(err, manager) {
        if (err) { return done(err); }
        if (!manager) { return done(null, false, { message: 'Unknown manager ' + manager_signin_email }); }
        manager.comparePassword(manager_signin_password, function(err, isMatch) {
            if (err) return done(err);
            if(isMatch) {
                console.log('Manager login OK : ' + manager_signin_email);
                return done(null, manager);
            } else {
                return done(null, false, { message: 'Invalid password' });
            }
        });
    });
}));

问题在于序列化/反序列化。 对于用户,我有这个:

passport.serializeUser(function(user, done) {
    done(null, user.id);
});

passport.deserializeUser(function(id, done) {
    UserModel.findById(id, function (err, user) {
        done(err, user);
    });
});

但是对于Manager模型我不知道怎么做。

【问题讨论】:

    标签: node.js express passport.js


    【解决方案1】:

    序列化时你可能会做这样的事情:

    if (isUser(user)) {
        // serialize user
        done(null, "user_"+user.id );
      } else if (isManager(user)) {
        // serialize manager
        done(null, "manager_"+user.id );
    
      }
    

    然后反序列化时检查前缀。

    【讨论】:

      【解决方案2】:

      我认为你想要的有一个未解决的问题 (https://github.com/jaredhanson/passport/issues/148)。

      或者,您可以更改序列化方法以包含信息,如果它是用户或管理器,则不仅是用户 ID,并且在反序列化时读取该信息并从正确的模型加载用户/管理器。

      【讨论】:

        【解决方案3】:

        以防万一还有人遇到这个问题。您可以检查您正在序列化的对象的类型。请注意,所有 by 对象都概括为 PrincipleInfo 对象。

        function PrincipleInfo(principleId, principleType, details) {
            this.principleId = principleId;
            this.principleType = principleType;
            this.details = details;
        }
        
        passport.serializeUser(function (userObjectThing, done) {
            //userObjectThing could be a User or a Sponsor
            var principleType = "user";
            var userPrototype =  Object.getPrototypeOf(userObjectThing);
            if (userPrototype === User.prototype) {
                principleType = "user";
            } else if (userPrototype === Sponsor.prototype) {
                principleType = "sponsor";
            } else if (userPrototype === Admin.prototype) {
                principleType = "admin";
            }
        
            var principleInfo = new PrincipleInfo(userObjectThing.id, principleType, '');
            done(null,principleInfo);
        });
        
            passport.deserializeUser(function (principleInfo, done) {
        
                if (principleInfo.principleType == 'user') {
                    User.findOne({
                        _id: principleInfo.principleId
                    }, '-salt -hashedPassword', function (err, user) { // don't ever give out the password or salt
                        done(err, user);
                    });
                } else if (principleInfo.principleType == 'sponsor') {
                    Sponsor.findOne({
                        _id: principleInfo.principleId
                    }, '-salt -hashedPassword', function (err, user) { // don't ever give out the password or salt
                        done(err, user);
                    });
                } else if (principleInfo.principleType == 'admin') {
                    Admin.findOne({
                        _id: principleInfo.principleId
                    }, '-salt -hashedPassword', function (err, user) { // don't ever give out the password or salt
                        done(err, user);
                    });
                }
        
            });
        

        【讨论】:

          猜你喜欢
          • 2014-05-13
          • 2013-12-01
          • 2017-08-21
          • 2020-11-22
          • 2019-05-11
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多