mongoose 如何使用passport验证用户和管理员

62lalag4  于 2023-10-19  发布在  Go
关注(0)|答案(1)|浏览(147)

我在护照运行本地策略,我有一个问题,它似乎验证用户的罚款,我可以有该用户在整个网站上持续在一个会话,但不是管理员。我在MongoDB中将用户和管理员帐户放在不同的集合中。我尝试了很多不同的方法,比如为管理员和用户设置不同的护照,为管理员和用户设置不同的数据库,但都无济于事。我已经到了原地不动的地步。我很感激你的建议!

//Passport.js
const LocalStrategy = require('passport-local').Strategy;
const mongoose = require('mongoose')
const bcrypt = require('bcrypt')

// Loads in user model
const User = require('../models/userModel')
//Loads in the admin model
const Admin = require('../models/adminModel')

module.exports = function (authUser){
  authUser.use(
    'authUser',new LocalStrategy({usernameField: 'username'}, (username, password, done)=>{
      //Match user
      const user = User.findOne({username: username})
      .then(user=>{
        if(!user){
          return done(null, false, {message: 'Incorrect Username'})
        }
        //Match password
        bcrypt.compare(password, user.password, (err, isMatch)=>{
          if(err) throw err;
          if (isMatch) {
            return done(null, user)
          }else {
            return done(null, false, {message: 'Incorrect password'})
          }
        })
      })
      .catch(err=>console.log(err));
    })
  )

  authUser.serializeUser((user, done) =>{
    done(null, user.id);
  });

  authUser.deserializeUser((id, done) =>{
    User.findById(id, (err, user) => {
      done(err, user);
    });
  });

  authUser.use(
    'admin',new LocalStrategy({usernameField: 'username'}, (username, password, done)=>{
      //Match user
      const admin = Admin.findOne({username: username})
      .then(admin=>{
        if(!admin){
          return done(null, false, {message: 'Incorrect Username'})
        }
        //Match password
        bcrypt.compare(password, admin.password, (err, isMatch)=>{
          if(err) throw err;
          if (isMatch) {
            return done(null, admin)
          }else {
            return done(null, false, {message: 'Incorrect password'})
          }
        })
      })
      .catch(err=>console.log(err));
    })
  )

  authUser.serializeUser((admin, done) =>{
    done(null, admin.id);
  });

  authUser.deserializeUser((id, done) =>{
    Admin.findById(id, (err, admin) => {
      done(err, admin);
    });
  });
}

//Authenticate.js
module.exports = {
  checkAuthenticated: function(req, res, next) {
    if (req.isAuthenticated()) {
      return next()
    }
    // req.flash('error_msg', 'please login to view this resource')
    res.redirect('/Users/Login')
  },
  checkNotAuthenticated: function(req, res, next) {
    if (req.isAuthenticated()) {
      return res.redirect('/')
    }
    // req.flash('error_msg', 'please login to view this resource')
    return next()
  },
  checkAdminAuthenticated: function(req, res, next) {
    if (req.isAuthenticated()) {
      return next()
    }
    // req.flash('error_msg', 'please login to view this resource')
    res.redirect('http://localhost:3000/Admin/SignIn')
  }
}

//Snippet from adminRoute.js
const passport = require('passport')
require('../config/passport.js')(passport)

app.get("/SignIn", checkNotAuthenticated,(req,res) =>{
  res.render("adminLogin.ejs")
})
app.get('/Orders', checkAdminAuthenticated, (req, res) => {
  Request.find({}).then(results => {
    res.render('orders.ejs', {
      Orders: results
    });
  })
})
// Login Handle
app.post('/SignIn', checkNotAuthenticated, (req,res, next)=>{
  passport.authenticate('admin',{
    successRedirect: '/AdminPage', //On success redirect to home
    failureRedirect: '/Admin/SignIn', //On failure redirect back to login page
    session: true,
    failureFlash: true
  })(req,res,next);
})
module.exports = app

//Snippet from userRoute.js
const passport = require('passport')
const authUser = new passport.Passport();
require('../config/passport.js')(authUser)
// DB config
const userDB = require('../config/keys').MongoURI
const User = require('../models/userModel')
app.get("/Login", checkNotAuthenticated,(req,res) =>{
  res.render("login.ejs")
})

app.delete('/logout', (req, res) => {
  req.logOut()
  res.redirect('/Users/Login')
})

app.get('/Register', checkNotAuthenticated,  (req,res)=>{
  res.render("register.ejs")
})

// Login Handle
app.post('/Login', checkNotAuthenticated,(req,res, next)=>{
  authUser.authenticate('authUser',{
    successRedirect: '/', //On success redirect to home
    failureRedirect: '/Users/Login', //On failure redirect back to login page
    session: true,
    failureFlash:true
  })(req,res,next);
})
module.exports = app

// snippet from app.js
const passport = require('passport')
const authUser = new passport.Passport();
require('./config/passport.js')(authUser)
    app.use(authUser.initialize())
    app.use(authUser.session())
    app.use('/Users', require('./routes/userRoute'))
    app.use('/Admin', require('./routes/adminRoute'))
dgtucam1

dgtucam11#

我试过了,它工作正常:

//login route
router.post('/', async (req, res, next) =>{

 const email = req.body.email;
 const password = req.body.password;
 const userRole = 'user';

 //Some validations here ...

 const user = await User.findOne({email: email});
   if (user.role == 'admin') userRole = 'admin';

   // Other validations here ...

 
 
 if(userRole == 'admin'){
        passport.authenticate('local', {

            successRedirect: '/whereAuthenticatedAdminsAlowed',
            failureRedirect: '/login',
            failureFlash: true

        })(req, res, next);
    }
    else{
        passport.authenticate('local', {

            successRedirect: '/whereAuthenticatedUsersAlowed',
            failureRedirect: '/login',
            failureFlash: true

        })(req, res, next);
    }
}

然后在admin route(/admin)中,我们需要一个中间件或一个函数来检查user是否是admin,因为我们需要访问user.role,首先我们应该在passport.serializeUser部分做一些更改:

//In local strategy module after creating strategies:
  passport.serializeUser((user,done) =>{
      return done(null, {
           id: user.id,
           role: user.role
       });
  });

   //In admin route:
    router.get('/admin', (req,res) =>{
       const userRole = req.session.passport.user.role;
    
       if (isAuthenticated() && userRole == 'admin'){
           res.render('admin');
       }
       else{
            res.status(401);
            res.redirect(// access denied page or...);
       }

    });

相关问题