Невозможно поймать условие 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);
});