【问题标题】:Multiple authentication not working passport.js多重身份验证不起作用 passport.js
【发布时间】:2021-06-26 03:07:47
【问题描述】:

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

     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);
    });
});

}

登录.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

【问题讨论】:

    标签: javascript node.js authentication passport.js


    【解决方案1】:

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

    我过去的做法是使用 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.

    【讨论】:

    • 感谢您的回答。我按照链接和您的答案中提到的步骤操作,但仍然显示错误用户不存在
    • 它显示错误用户不存在员工不存在但它们都存在于数据库中
    • 那么错误发生在您的反序列化用户函数内部吗?当你运行User.findById(sessionConstructor.userId)
    • 感谢我的朋友帮助现在代码工作。问题出在我的护照身份验证中。
    猜你喜欢
    • 2013-06-29
    • 1970-01-01
    • 2018-02-17
    • 2015-11-01
    • 2016-04-28
    • 2014-11-18
    • 2018-03-26
    • 2014-11-06
    • 1970-01-01
    相关资源
    最近更新 更多