Невозможно поймать условие 401, используя логин Passport

Я использую PassportJS с локальной стратегией и passport-local-mongoose. Вот мой скрипт входа в систему:

// Configure Passport (server.js)
// ---------------------------------------------------------------
passport.use(new LocalStrategy(User.authenticate()));
passport.serializeUser(User.serializeUser());
passport.deserializeUser(User.deserializeUser());
// ---------------------------------------------------------------

,

// POST to /login (authenticate.js)
// ---------------------------------------------------------------
router.post('/login', (req, res) => {
    // server-side validation
  const errors = {
    username: Validator.validateusername(req.body.username),
    password: Validator.validatepassword(req.body.password),
  };
  if (!isEmpty(errors)) return res.send(JSON.stringify({ error: errors }));

  passport.authenticate('local')(req, res, () => {
    // If logged in, we should have user info to send back
    if (req.user) {
      const userdata = JSON.stringify(req.user);
      const token = jwt.sign({
        username: req.user.username,
        firstName: req.user.firstName,
        lastName: req.user.lastName,
        email: req.user.email,
        img: req.user.img,
      }, process.env.JWT_SECRET);
      res.cookie('token', token);
      return res.send(userdata);
    }
    // Otherwise return an error
    return res.send(JSON.stringify({ error: 'There was an error logging in' }));
  });
});

Это прекрасно работает, за исключением случаев, когда есть ошибка входа в систему. Если по какой-либо причине происходит сбой входа (401 или 500), не должен ли этот скрипт вернуть There was an error logging in сообщение? Вместо этого он просто возвращает 401 Unauthorized?

Схема, которую ищет эта аутентификация:

const { mongoose } = require('../config/dbconfig');

const Schema = mongoose.Schema;
const passportLocalMongoose = require('passport-local-mongoose');

const User = new Schema({
  username: {
        type: String,
        lowercase: true,
        required: true,
        unique: true,
    },
  password: {
        type: String,
        select: false,
        required: true,
    },
  firstName: {
        type: String,
        required: true,
    },
  lastName: {
        type: String,
        required: true,
    },
  email: {
        type: String,
        lowercase: true,
        required: true,
        unique: true,
    },
  img: {
        type: String,
    },
}, { timestamps: true });

User.plugin(passportLocalMongoose);

module.exports = mongoose.model('User', User);

1 ответ

Решение

Вы называете стратегию немного неправильной. Вы должны использовать его в качестве промежуточного программного обеспечения или использовать собственный способ обратного вызова. Ваша комбинация между ними - вы называете стратегию промежуточным программным обеспечением, но предоставляете свою собственную next функция промежуточного программного обеспечения. Так как аутентификация называется промежуточным ПО, но нет failureRedirect опция предусмотрена, Паспорт вернет 401 по умолчанию. next Функция вызывается при успешной аутентификации, и в вашем случае это не следующая промежуточная программа, а функция обратного вызова.

Чтобы использовать пользовательский обратный вызов, вы должны написать обработчик маршрута следующим образом:

app.post('/login', (req, res, next) => {
  // ...
  passport.authenticate('local', (err, user, info) => {
    if (err) { return next(err); }
    if (user) {
      // ...
      req.login(user, (err) => {
        if (err) { return next(err); }
        return res.send(userdata);
      });
    } else {
      return res.status(401).send({ error: 'There was an error logging in' });
    }
  })(req, res, next);
});
Другие вопросы по тегам