Node.js 在PassportJS中使用多个本地策略

Node.js 在PassportJS中使用多个本地策略,node.js,local,passport.js,Node.js,Local,Passport.js,我正在尝试对PassportJS使用多种本地策略。我不想使用本地、facebook和gmail等。 我有两组用户存储在不同的对象中,我想使用本地策略对它们进行身份验证。目前,我不能对两者使用相同的本地策略,因为它们具有不同的对象属性,这使我需要查询不同的对象。有没有办法做到这一点?或者对此提出任何建议都将不胜感激。我认为这是不可能的,因为据我所知,当第一个策略失败时,您需要某种方法将请求“传递”给第二个策略,我认为这是不可能的 但您可能可以使用一种本地策略,并尝试使用这两种方法对传入数据进行身份

我正在尝试对PassportJS使用多种本地策略。我不想使用本地、facebook和gmail等。
我有两组用户存储在不同的对象中,我想使用本地策略对它们进行身份验证。目前,我不能对两者使用相同的本地策略,因为它们具有不同的对象属性,这使我需要查询不同的对象。有没有办法做到这一点?或者对此提出任何建议都将不胜感激。

我认为这是不可能的,因为据我所知,当第一个策略失败时,您需要某种方法将请求“传递”给第二个策略,我认为这是不可能的

但您可能可以使用一种本地策略,并尝试使用这两种方法对传入数据进行身份验证

作为一个简单的示例(使用Mongoose作为示例数据库):


对于序列化/反序列化,您可能需要在传递给
done
user
对象中存储一些属性,以指示反序列化用户所需的模型。

您可以命名本地策略以将它们分开

// use two LocalStrategies, registered under user and sponsor names

      // add other strategies for more authentication flexibility
  passport.use('user-local', new LocalStrategy({
      usernameField: 'email',
      passwordField: 'password' // this is the virtual field on the model
    },
    function(email, password, done) {
      User.findOne({
        email: email
      }, function(err, user) {
        if (err) return done(err);

        if (!user) {
          return done(null, false, {
            message: 'This email is not registered.'
          });
        }
        if (!user.authenticate(password)) {
          return done(null, false, {
            message: 'This password is not correct.'
          });
        }
        return done(null, user);
      });
    }
  ));

    // add other strategies for more authentication flexibility
    passport.use('sponsor-local', new LocalStrategy({
            usernameField: 'username',
            passwordField: 'password' // this is the virtual field on the model
        },
        function(username, password, done) {
            Sponsor.findOne({
                'primaryContact.username': username
            }, function(err, sponsor) {
                if (err) return done(err);

                if (!sponsor) {
                    return done(null, false, {
                        message: 'This email/username is not registered.'
                    });
                }
                if (!sponsor.authenticate(password)) {
                    return done(null, false, {
                        message: 'This password is not correct.'
                    });
                }
                return done(null, sponsor);
            });
        }
    ));
稍后的控制器代码按名称引用它们

/**
 * User Login
 */
exports.loginUser = function (req, res, next) {
    passport.authenticate('user-local', function(err, user, info) {
        var error = err || info;
        if (error) return res.json(401, error);

        req.logIn(user, function(err) {

            if (err) return res.send(err);
            res.json(req.user.userInfo);
        });
    })(req, res, next);
};

/**
 * Sponsor Login
 */
exports.loginSponsor = function (req, res, next) {
    passport.authenticate('sponsor-local', function(err, sponsor, info) {
        var error = err || info;
        if (error) return res.json(401, error);

        req.logIn(sponsor, function(err) {
            if (err) return res.send(err);
            res.json(req.sponsor.profile);
        });
    })(req, res, next);
};
稍后,当需要序列化用户时,您可能希望执行类似的操作

// serialize
passport.serializeUser(function(user, done) {            
  if (isUser(user)) {
    // serialize user
  } else if (isSponsor(user)) {
    // serialize company
  }
});

您可以在多个本地策略中使用类似的内容

passport.use('local.one', myLocalStrategy1);
passport.use('local.two', myLocalStrategy2);
passport.use('local.three', myLocalStrategy3);

...

app.get('/login/s1', passport.authenticate('local.one');
app.get('/login/s2', passport.authenticate('local.two');
app.get('/login/s3', passport.authenticate('local.three');
1) 在用户注册表中默认保存角色:数据库中的“客户” 2) 在管理员注册表中默认保存角色:数据库中的“管理员”

[Note- If you use mongodb as a database in registration schema make-

role:{
type: String,
default: 'customer' or 'admin' //Manage respectively
},

Important- 'This uses cookie for session login'
'You can do this on your own way :)']
战略 连载 用于反序列化
  • 创建两个本地策略

    passport.use('userLocal',新的LocalStrategy(User.authenticate())
    
    passport.use('clientLocal',新的LocalStrategy(Client.authenticate())

  • 2.认证

    passport.authenticate('userLocal')(req, res, function () {
        res.redirect('/profile');
      });
    and
    passport.authenticate('clientLocal')(req, res, function () {
        res.redirect('/client');
      });
    
    3.对于序列化用户和反序列化用户

    passport.serializeUser(function(user, done) { 
      done(null, user);
    });
    
    passport.deserializeUser(function(user, done) {
      if(user!=null)
        done(null,user);
    });
    

    我忘了接受这个,但是谢谢!由此我明白了我需要做什么。!谢谢你的评论,我使用了类似的解决方案。谢谢你的回复!也使用了类似的一个,但具有不同的目录。谢谢。准备好后(以及我自己真正理解时)将发布新答案,以解释我的解决方案。文档中是否有此内容?如何使用passport local mongoose Package进行同样的操作?如何反序列化用户?我的一个策略是查询来宾表,而另一个策略是查询办公室表。我不知道,我想我会坚持不使用passportjs,用bcrypt和随机盐进行哈希不是一个很难的问题
    passport.serializeUser((user, done) => {
            done(null, { _id: user.id, role: user.role });
    });
    
    passport.deserializeUser((login, done) => {
            if (login.role === 'customer') {
                User.findById(login, function (err, user) {
                    if (user)
                        done(null, user);
                    else
                        done(err, { message: 'User not found' })
                });
            }
            else if (login.role === 'admin') {
                Admin.findById(login, (err, admin) => {
                    if (admin)
                        done(null, admin);
                    else
                        done(err, { message: 'Admin not found' })
                });
            }
            else {
                done({ message: 'No entity found' }, null);
            }
        });
    
    passport.authenticate('userLocal')(req, res, function () {
        res.redirect('/profile');
      });
    and
    passport.authenticate('clientLocal')(req, res, function () {
        res.redirect('/client');
      });
    
    passport.serializeUser(function(user, done) { 
      done(null, user);
    });
    
    passport.deserializeUser(function(user, done) {
      if(user!=null)
        done(null,user);
    });