中间件在快速调用返回其中一个后没有停止



我的快速应用程序中的中间件出现问题,我有以下路线:

app.post(
'/api/auth/signup',
[
verifySignUp.checkDuplicateUsernameOrEmail,
verifySignUp.checkRolesExist
],
controller.signup
);

有两个中间件checkDuplicateUsernameOrEmailcheckRolesExist如下所示:

const checkDuplicateUsernameOrEmail = (req, res, next) => {
console.log('checkDuplicateUsernameOrEmail');
User.findOne({username: req.body.username}).exec()
.then(user => {
if (user) {
console.log("user name exists");
return fail(res, {message: 'This username already exists'});
}
return User.findOne({email: req.body.email}).exec()
})
.then(user => {
if (user) {
return fail(res, {message: 'This email already exists'});
}
next();
})
.catch(error => {
console.log(error);
fail(res, {message: 'Database internal error occured.'});
});
};
const checkRolesExist = (req, res, next) => {
console.log('checkRolesExist');
console.log(req.body.roles);
for (const role of req.body.roles) {
if (!ROLES.includes(role)) {
return fail(res, {message: `${role} is not a valid role`});
}
}
next();
};
const fail = (res, err) => {
const message = err.message || 'Encountered a server error';
const status = err.status || 500;
res.status(status).json({status, message});
}

我使用之前已经使用过的用户名发出请求,在控制台中我按预期得到user name exists,但是应用程序继续调用checkRolesExist,中间件的执行不应该在返回时停止吗?我哪里做错了什么?

那是因为return fail返回...无。您是在then()回调函数中返回内容,而不是在checkDuplicateUsernameOrEmail()中返回内容。所以,执行继续,你点击下一个.then().

async/await风格,它会让你的生活更轻松:

const checkDuplicateUsernameOrEmail = async(req, res, next) => {
console.log('checkDuplicateUsernameOrEmail');
try {
if ( await User.findOne({ username: req.body.username }).exec() ) {
console.log("user name exists");
return fail(res, { message: 'This username already exists' });
}
if ( await User.findOne({ email: req.body.email }).exec()) {
return fail(res, { message: 'This email already exists' });
}
next();
} catch (error) {
console.log(error);
fail(res, { message: 'Database internal error occured.' });
}
};

如果您希望它们以除非第一次通过否则不触发checkRolesExist的特定顺序运行,请执行以下操作:

app.post(
'/api/auth/signup',
verifySignUp.checkDuplicateUsernameOrEmail,
verifySignUp.checkRolesExist,
controller.signup
);

最新更新