node.js - 如何为两种不同的用户类型编码登录(护照)身份验证?节点.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');
});
解决方案
如果您使用的是 Travesty-Media 在他的一些视频中使用的 mongoose 和 mongoDB,那么这两种不同类型的用户应该通过用户 Schema 以及通过 Web 应用程序不同部分的权限来区分。
使用您为患者用户使用的相同护照代码,它可以工作。Passport 获取用户信息并将其转换为 Bearer 身份验证令牌并将其发送给客户端,然后当它从客户端接收到它时,它会对其进行解码以查看什么样的用户正在登录......
即使有 2 个不同的患者用户,不同的用户也有不同的信息但相同的 Passport 逻辑。所以从病人到医生关于护照的逻辑是一样的。
如果您希望患者可以访问您的应用程序的不同路由,您需要在该路由中插入一个中间件,以检查用户类型是否与您想要的相同,但在护照获得信息之后它从客户端收到的令牌。
推荐阅读
- java - 无法使用具有文本逗号 csv 的值拆分字符串
- excel - Excel 文件缺少对 Microsoft Windows Common Controls-2 的引用
- python - pydrive.auth.RefreshError:访问令牌刷新失败:invalid_grant:令牌已过期或撤销
- c - 使用 CGO 将 Go 嵌套的结构数组转换为 C?
- javascript - NodeList 元素上的 forEach() 函数
- kubernetes - 如何在 kubernetes v1.19.0 上将“--token-auth-file=SOMEFILE”标志设置为 apiserver
- kotlin - Kotlin 中可空字符串的重载解析歧义错误
- ruby-on-rails - 仅当 current_user 是管理员时才在模型中进行验证 - Rails
- javascript - Ajax 不工作 - 提交时数据和页面不会发生变化
- reactjs - TypeError:无法读取未定义的属性“国家” - React-Redux