javascript - 即使抛出错误,猫鼬也会返回文档
问题描述
我有一个 Express.js 路由,可以通过用户名和密码从我的 MongoDB 数据库中检索用户。我的目标是从请求正文中获取用户名和密码,通过用户名找到用户,然后验证密码是否匹配。如果密码匹配,我想返回用户对象和 200 状态码,如果密码不匹配,我想返回 404 和错误消息。
目前我的路线正在运行,但即使密码不匹配,用户也会始终返回。我正在检查它们是否匹配并抛出错误,但它似乎没有像我预期的那样抛出。理想情况下,如果密码在我的服务调用中不匹配,我想抛出一个错误,并在我的路由中捕获它以返回正确的状态代码。
我试图在我的路线中捕获错误并从服务返回被拒绝的承诺,但仍然返回用户。我的预感是在findOne
返回记录后运行接受的回调?
我在控制台中收到 UnhandledPromiseRejectionWarning 对应的行,如果密码不匹配,我将抛出错误:
app_1 | GET /user 200 221 - 4.297 ms
app_1 | (node:257) UnhandledPromiseRejectionWarning: Error: Password does not match
app_1 | at /usr/src/app/services/userService.ts:17:37
app_1 | at Generator.next (<anonymous>)
app_1 | at fulfilled (/usr/src/app/services/userService.ts:5:58)
服务器.ts
注意
我find
在导入时重命名为findUser
via
find as findUser
app.get('/user', authenticateToken, async (req: Request, res: Response): Promise<void> => {
const user = await findUser(req.body.username, req.body.password);
if (!user) {
res.status(404).send();
return;
}
res.status(200).send({ user });
});
用户服务.ts
const find = (username: string, password: string) => {
return User.findOne({ username }, async (err: Error, user: any) => {
if (err) throw err;
const passwordMatches = await user.validatePassword(password);
if (!passwordMatches) throw Error("Password does not match")
});
}
user.ts(用户猫鼬模型)
import mongoose from 'mongoose';
import bcrypt from 'bcrypt';
interface User {
username: string;
password: string;
isModified: (string: any) => boolean;
}
const SALT_WORK_FACTOR = 10;
const userSchema = new mongoose.Schema({
username: { type: String, required: true, index: { unique: true } },
password: {
type: String,
unique: false,
required: true
}
},
{ timestamps: true }
);
userSchema.pre('save', function(next) {
const user = this as unknown as User;
if (!user.isModified('password')) return next();
bcrypt.genSalt(SALT_WORK_FACTOR, (err: any, salt: any) => {
if (err) return next(err);
bcrypt.hash(user.password, salt, function(err: any, hash: any) {
if (err) return next(err);
user.password = hash;
next();
});
});
});
userSchema.methods.validatePassword = function (pass: string) {
return bcrypt.compare(pass, this.password);
};
const User = mongoose.model('User', userSchema);
export { User };
解决方案
在我的userService
我改变了我查询的方式findOne
来解决这个问题。我从阅读模型上的猫鼬 findOne 是否返回承诺?
const find = (username: string, password: string) => {
return User.findOne({ username }).exec().then((user: any) => {
const passwordMatches = user.validatePassword(password);
if (!passwordMatches) throw Error("Password does not match")
return user;
});
}
推荐阅读
- node.js - 在谷歌应用引擎上运行 firebase admin 和 firestore
- dictionary - 在 Terraform 中将地图与变量合并
- ldap - Keycloak 无法将用户组映射从 LDAP 传播到用户组映射
- python - Python - 如何使两个非常相似的代码块变得更短?
- c++ - 将偶数相加并乘以奇数
- r - 您可以使用substitute() 在R 中从文本字符串创建一个函数吗?
- excel - Excel公式返回两个日期之间的所有匹配项
- flutter - 多行颤动文本字段占据所有灵活空间,右填充丑陋
- c++ - 如何让 VS Code 提出更有限的重命名?
- point-clouds - PLY 文件格式 - 带有颜色 RGB 信息的点云的正确标题是什么?