#mongodb #jwt
Вопрос:
Я создаю панель администратора, чтобы учителя могли входить и регистрироваться, а ученики-входить и регистрироваться. Я настроил стратегию jwt и локальную стратегию, используя passport.js. Мой вопрос в том, могу ли я внедрить как учителей, так и пользователей в паспорт стратегии jwt с использованием моделей mongodb? вот моя попытка.
const passport = require('passport');
const { Strategy: JwtStrategy, ExtractJwt } = require('passport-jwt');
const LocalStrategy = require('passport-local');
const { secret } = require('../config');
const Teacher = require('../models/Teacher');
const Student = require('../models/Student');
ниже у меня есть моя стратегия jwt, в которую я включаю пользователей и учителей
const jwtOptions = {
jwtFromRequest: ExtractJwt.fromHeader('authorization'),
secretOrKey: process.env.SECRET || secret,
};
const tjwtLogin = new JwtStrategy(jwtOptions, async (payload, done) =>
{
try {
console.log('im hitting inside jwt')
const user = await User.findById(payload.sub).select('-password');
const teacher = await Teacher.findById(payload.sub).select('-
password');
if (!user || !teacher) {
return done(null, false);
}
return done(null, user || teacher );
} catch (e) {
return done(e, false);
}
});
here is my local strategy
const localOptions = { usernameField: 'email' };
const tlocalLogin = new LocalStrategy(localOptions, async (email,
password, done) => {
try {
const user = await User.findOne({ email });
const teacher = await Teacher.findOne({ email });
if (!user || !teacher) { return done(null, false); }
const isMatch = await user.comparePassword(password);
const isTMatch = await teacher.comparePassword(password);
if (!isMatch || !isTMatch ) { return done(null, false); }
return done(null, user || teacher );
} catch (e) {
return done(e);
}
});
здесь я определяю стратегию.
passport.use(tjwtLogin,ulocalLogin);
passport.use(tlocalLogin,ujwtLogin);
Ответ №1:
Похоже, что для аутентификации вы используете много кода и жестко закодированных условий. Как будто в будущем нужно будет добавить какое-то новое правило.
Что вы можете сделать, так это использовать единую модель БД для пользователей и добавить дополнительный параметр typeofuser(ученик и учитель) в вашем случае. И выполните аутентификацию с использованием единой стратегии аутентификации и перенаправьте пользователя в зависимости от роли пользователя.
Ответ №2:
вот успешный подход. проверьте, не являются ли пользователи и учащиеся нулевыми.
const passport = require('passport');
const { Strategy: JwtStrategy, ExtractJwt } = require('passport-jwt');
const LocalStrategy = require('passport-local');
const { secret } = require('../tconfig');
const Teacher = require('../models/Teacher');
const User = require('../models/User');
const jwtOptions = {
jwtFromRequest: ExtractJwt.fromHeader('authorization'),
secretOrKey: process.env.SECRET || secret,
};
const tjwtLogin = new JwtStrategy(jwtOptions, async (payload, done) => {
try {
const teacher = await Teacher.findById(payload.sub).select('-password');
const user = await User.findById(payload.sub).select('-password');
if(teacher){
if (!teacher ) {
return done(null, false);
}
return done(null, teacher );
}
if(user){
if (!user ) {
return done(null, false);
}
return done(null, user );
}
} catch (e) {
return done(e, false);
}
});
const localOptions = { usernameField: 'email' };
const tlocalLogin = new LocalStrategy(localOptions, async (email, password, done) => {
try {
const teacher = await Teacher.findOne({ email });
const user = await User.findOne({ email });
if(teacher){
if (!teacher ) { return done(null, false); }
const isMatch = await teacher.comparePassword(password);
if (!isMatch) { return done(null, false); }
return done(null, teacher );
}
if(user){
if (!user ) { return done(null, false); }
const isMatch = await user.comparePassword(password);
if (!isMatch) { return done(null, false); }
return done(null, user );
}
} catch (e) {
return done(e);
}
});
passport.use(tjwtLogin);
passport.use(tlocalLogin);