Можете ли вы добавить два типа пользователей в аутентификацию стратегии jwt?

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