首页 > 解决方案 > 如何为两种不同的用户类型编码登录(护照)身份验证?节点.js

问题描述

我是 Node.js 的新手。

对于我的应用程序,我有两种不同类型的用户,即医生和患者。目前,我一直在为患者的登录和注册进行编码,并且可以正常工作。我开始为医生编写登录代码,但它似乎不起作用。下面是passport.js。我观看了一段视频(https://www.youtube.com/watch?v=6FOq4cUdH8k&ab_channel=TraversyMedia)来学习如何编写登录和注册代码。

我认为问题出在passport.js中,当涉及到第二个用户时,我不确定如何对其进行编码。

const LocalStrategy = require('passport-local').Strategy;
const bcrypt = require('bcryptjs');

const Patient = require('../models/patients');

module.exports = function(passport) {
  passport.use(
    new LocalStrategy({ usernameField: 'email' }, (email, password, done) => {
      Patient.findOne({
        email: email
      }).then(patient => {
        if (!patient) {
          return done(null, false, { message: 'That email is not registered' });
        }

        bcrypt.compare(password, patient.password, (err, isMatch) => {
          if (err) throw err;
          if (isMatch) {
            return done(null, patient);
          } else {
            return done(null, false, { message: 'Password is incorrect' });
          }
        });
      });
    })
  );

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

  passport.deserializeUser(function(id, done) {
    Patient.findById(id, function(err, patient) {
      done(err, patient);
    });
  });
  
const Doctor = require('../models/doctors');

module.exports = function(passport) {
  passport.use(
    new LocalStrategy({ usernameField: 'email' }, (demail, dpassword, done) => {
      Doctor.findOne({
        demail: demail
      }).then(doctor => {
        if (!doctor) {
          return done(null, false, { message: 'That email is not registered' });
        }

        bcrypt.compare(dpassword, doctor.dpassword, (err, isMatch) => {
          if (err) throw err;
          if (isMatch) {
            return done(null, doctor);
          } else {
            return done(null, false, { message: 'Password is incorrect' });
          }
        });
      });
    })
  );

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

  passport.deserializeUser(function(id, done) {
    Doctor.findById(id, function(err, doctor) {
      done(err, doctor);
    });
  });
  
}}:

这是我在路线中的医生.js

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

const Doctor = require('../models/doctors');

router.get('/doctorregister', (req, res) => res.render('Doctorregister'));

router.get('/doctorlogin', (req, res) => res.render('Doctorlogin'));

module.exports = router;


router.post('/doctorregister', (req, res) => {
    const { dname, dqualification, dlocation, dpractice, demail, dmobileno, dpassword, dpassword2 } = req.body;
    let errors = [];
  
    if (!dname|| !dqualification || !dlocation || !dpractice || !demail || !dmobileno  || !dpassword || !dpassword2) {
      errors.push({ msg: 'Please enter all fields' });
    }
  
    if (dpassword != dpassword2) {
      errors.push({ msg: 'Passwords do not match' });
    }
  
    if (dpassword.length < 6) {
      errors.push({ msg: 'Password must be at least 6 characters' });
    }
  
    if (errors.length > 0) {
      res.render('doctorregister', {
        errors,
        dname, 
        dqualification, 
        dlocation, 
        dpractice,
        demail, 
        dmobileno, 
        dpassword, 
        dpassword2
      });
    } else {
        Doctor.findOne({ demail: demail }).then(doctor => {
        if (doctor) {
          errors.push({ msg: 'Email already exists' });
          res.render('register', {
            errors,
            dname, 
            dqualification, 
            dlocation, 
            dpractice,
            demail, 
            dmobileno, 
            dpassword, 
            dpassword2
          });
        } else {
          const newDoctor = new Doctor({
            dname, 
            dqualification, 
            dlocation, 
            dpractice,
            demail, 
            dmobileno, 
            dpassword,
          });
  
         //hashing password in the database
         bcrypt.genSalt(10, (err, salt) => {
            bcrypt.hash(newDoctor.dpassword, salt, (err, hash) => {
              if (err) throw err;
              newDoctor.dpassword = hash;
              newDoctor.save()
                .then(doctor => {
                  req.flash('success_msg', 'You are now registered and can log in')  
                  res.redirect('/doctors/doctorlogin');
                })
                .catch(err => console.log(err));
            });
          });
        }
      });
    }
});
 
router.post('/doctorlogin', (req,res, next) => {
  passport.authenticate('local', {
    successRedirect: '/doctordashboard',
    failureRedirect: '/doctors/doctorlogin',
    failureFlash: true
  })(req, res, next);
});

router.get('/logout', (req, res) => {
  req.logout();
  req.flash('You are logged out');
  res.redirect('/doctors/doctorlogin');
});

标签: node.jsexpressauthenticationpassport.js

解决方案


如果您使用的是 Travesty-Media 在他的一些视频中使用的 mongoose 和 mongoDB,那么这两种不同类型的用户应该通过用户 Schema 以及通过 Web 应用程序不同部分的权限来区分。

使用您为患者用户使用的相同护照代码,它可以工作。Passport 获取用户信息并将其转换为 Bearer 身份验证令牌并将其发送给客户端,然后当它从客户端接收到它时,它会对其进行解码以查看什么样的用户正在登录......

即使有 2 个不同的患者用户,不同的用户也有不同的信息但相同的 Passport 逻辑。所以从病人到医生关于护照的逻辑是一样的。

如果您希望患者可以访问您的应用程序的不同路由,您需要在该路由中插入一个中间件,以检查用户类型是否与您想要的相同,但在护照获得信息之后它从客户端收到的令牌。


推荐阅读