多重身份验证无效 passport.js

Multiple authentication not working passport.js

我正在尝试通过多种策略对多个用户进行身份验证。我有 2 table 第一个是用户 table 第二个是员工但是当我尝试登录时它正在工作显示错误

     User not exist 

当我只使用单一身份验证策略时,它是有效的,但当我使用多个策略时,它显示错误

Auth.js

 const LocalStrategy = require('passport-local').Strategy
 const bcrypt = require('bcrypt')
 const User = require('../models/authUserModel')
 const Employee = require('../models/employeeModel')
 module.exports = function (passport) {
      passport.use("user-local",
         new LocalStrategy({usernameField: "email"}, function (email, password, done) {   
           User.findOne({email: email})
            .then(user => {
                if (!user) {
                    return done(null, false, ({message: 'Email not exist'}))
                }
                bcrypt.compare(password, user.password, (err, isMatch) => {
                    if (err) throw err
                    if (isMatch) {
                        return done(null, user)
                    } else {
                        return done(null, false, ({message: 'Password incorrect'}))
                    }
                })
            }).catch(err => console.log(err))

    })
)
passport.use('local',
    new LocalStrategy({usernameField:"email"}, function (email, password, done){
        Employee.findOne({email:"email"})
            .then(user=>{
                if(!user){
                    return done(null, false,'employee not exist')
                }
                bcrypt.compare(password, user.password, (err, isMatch)=>{
                    if(isMatch){
                        return done(null, user)
                    }
                    else {
                        return done(null, false, 'password or email is incorrect')
                    }
                })
            }).catch(err=>console.log(err))
    })
)

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

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

}

Login.js

  let express = require('express');
  let router = express.Router();
  const passport = require('passport')



  router.get('/login', function(req, res, next) {
      res.render('login');
  })
  router.post('/login', function (req, res, next) {
     passport.authenticate("user-local", function (err, user, info) {
     if (err) {
        return next(err)
     }
     if (!user) {
     console.log('User not exist')
        return res.render('login')
    }
    req.logIn(user, function (err) {
        if (err) {
           return next(err)
        }  
        req.session.isLoggedIn = true
        req.session.user = user
        req.session.save(err => {
            console.log(err)
            if (req.isAuthenticated()) {
               return res.redirect('/customerMenu')
            }
            console.log('user not exist')
            return res.render('login')
         })
      })
  })(req, res, next)

passport.authenticate('local', function (err, user, info){

 if(err){
   return next(err)
}
if(!user)
{
  console.log("employee not exist")
  return res.render('login')
}

req.logIn(user,function (err){

  if(err){return next(err)}

  req.session.isLoggedIn = true

  req.session.user = user

  req.session.save(err=>{


    console.log(err)

    if (req.isAuthenticated()) {

      return res.redirect(200,'/employeeMenu')

    }

    console.log('user not exist')

    return res.render('login')

  })
})

  })(req, res, next)
 })
 function isLoggedIn(req, res, next){
     if(req.isAuthenticated()){
        req.isLogged = true
        return next();
     }
     else{
       req.isLogged = false
       return next()
     }
 }
 module.exports = isLoggedIn
 module.exports = router

我认为您需要编辑 .serializeUser().deserializeUser() 函数,以便 passport 知道您尝试序列化和反序列化的用户类型。

我过去的做法是使用 SessionConstructor,将用户的 ID 和他们所在的用户类型都放在一个对象中。然后,您可以在反序列化函数中使用它来确定您尝试登录的用户类型。

function SessionConstructor(userId, userGroup){
    this.userId = userId;
    this.userGroup = userGroup;
}

passport.serializeUser((user, done) => {
    let userGroup = 'user';
    if (//condition to tell if it is the other user type){
        userGroup = 'employee';
    };
    let sessionConstructor = new SessionConstructor(user.id, userGroup)

    done(null, sessionConstructor);
});

passport.deserializeUser((sessionConstructor, done) => {
    if (sessionConstructor.userGroup == 'user'){
        User.findById(sessionConstructor.userId).then(user => done(null, user));
    } else if (sessionConstructor.userGroup == 'employee'){
        Employee.findById(sessionConstructor.userId).then( employee=> done(null, employee));
    }
});

然而,您需要为 .serializeUser() 中的 if 语句考虑一个条件,该条件将告诉您它是哪种类型的用户。如果您在发送到 .serializeUser() 的用户对象中包含一个唯一标识符,那么您可以通过检查来判断。例如,在您的用户对象中有一个名为 employee 的键,如果提交它的是员工,则值为 true,否则为 false。如果您选择此实现,它将看起来像这样。

passport.serializeUser((user, done) => {
    let userGroup = 'user';
    if (user.employee){
        userGroup = 'employee';
    };
    let sessionConstructor = new SessionConstructor(user.id, userGroup)

    done(null, sessionConstructor);
});

除此之外,我认为下面的代码应该可以工作,但请随时提出有关此方法的任何问题,我会尽力回答!

Here is a link to where I learned about how to do this.