为何我用这两段代码都无法从Mongo Atlas删除数据?
两段MongoDB删除代码的问题分析
第一段代码问题解析
//DELETE POST router.delete("/:id", async (req, res) => { try { const post = await Post.findById(req.params.id); if (post.username === req.body.username) { try { await post.delete(); res.status(200).json("Post has been deleted..."); } catch (err) { res.status(500).json(err); } } else { res.status(401).json("You can delete only your post!"); } } catch (err) { res.status(500).json(err); } });
- 空指针触发500错误:如果
Post.findById返回null(比如ID格式无效或数据查询不到),后续访问post.username会抛出TypeError,直接跳到外层catch返回500。必须先判断post是否存在,再执行后续逻辑。 - 方法已废弃:Mongoose文档实例的
delete()方法已被废弃,应改用deleteOne()。 - 验证逻辑不安全:直接用前端传入的
req.body.username做权限验证存在风险,建议通过已认证的用户信息(比如JWT解析出的用户ID)匹配帖子的作者ID,避免前端篡改参数。
修复示例片段:
const post = await Post.findById(req.params.id); if (!post) return res.status(404).json("Post not found"); // 假设当前登录用户ID存储在req.user.id中 if (post.authorId.toString() !== req.user.id) { return res.status(401).json("You can delete only your post!"); } await post.deleteOne(); res.status(200).json("Post has been deleted...");
第二段代码问题解析
router.delete("/:id", async (req, res) => { if (req.body.userId === req.params.id) { if (req.body.password) { const salt = await bcrypt.genSalt(10); req.body.password = await bcrypt.hash(req.body.password, salt); } try { await Post.delete(); res.status(200).json("Post has been deleted..."); } catch (err) { res.status(500).json(err); } } else { res.status(401).json("You can delete only your account!"); } });
- 核心逻辑错误:
req.body.userId === req.params.id是把用户ID和帖子ID做对比,这完全不符合“验证用户是否有权删除帖子”的逻辑,正确逻辑应该是帖子的作者ID等于当前登录用户ID。 - 冗余无意义代码:删除帖子不需要处理密码加盐哈希,这部分代码属于错误添加的冗余内容。
- 危险操作:
Post.delete()会删除整个集合的所有数据,且该方法已废弃,正确删除单条帖子应使用Post.findByIdAndDelete(req.params.id),或先查询文档再调用deleteOne()。 - 提示信息错误:提示文案写成了“只能删除你的账户”,和删除帖子的场景不匹配。
内容的提问来源于stack exchange,提问作者Seyn
相关产品推荐
相关产品推荐

