【问题标题】:Node function codes to delete user by admin is not working管理员删除用户的节点功能代码不起作用
【发布时间】:2021-10-31 21:56:37
【问题描述】:

我在构建中学习。我正在用 Nodejs、reactjs 和 mongodb 构建一个博客 CMS。 我有两个角色:用户和管理员。我希望管理员能够删除任何用户。我编写了使用户能够删除他/她自己的帐户的代码。如何让管理员能够通过单击该用户旁边的按钮来删除该用户?

到目前为止,这是我的代码: 用户删除他/她自己的代码。一旦用户删除了他/她的自我,与该用户相关的所有内容也将被删除。这工作正常。

//delete logic

 router.delete("/:id", async (req, res) =>{
 if(req.body.userId === req.params.id){//we checked if the user id matched

    try{
        const user = await User.findById(req.params.id)//get the user and assign it to user variable
        try{
            await Post.deleteMany({username: user._id})//deleting user posts once the username matches with the variable user object .username
            await Comment.deleteMany({author: user._id})//delete user's comment by checking the comment author's id.
            await Reply.deleteMany({author: user._id})//deletes user's replies
            await User.findByIdAndDelete(req.params.id)//delete the user
            res.status(200).json("User has been deleted")
        } catch(err){
            res.status(500).json(err) //this handles the error if there is one from the server
        }
    }catch(err){
        res.status(404).json("User not found")
    }

       
  } else{
   res.status(401).json("You can only update your account!")
  }

 });

我如何尝试为管理员编写代码以删除用户:

/delete a user by an admin

 router.delete("/:id", async (req, res) =>{
  if(req.body.userId === req.params.id){
     const user = await User.findOne({username: req.body.username})
   if(user && user.role === "admin"){
    try{
        const regUser = await User.findById(req.params.id)//get the user and assign it to  user variable
        try{
            await Post.deleteMany({username: regUser._id})//deleting user posts once the username matches with the variable user object .username
            await Comment.deleteMany({author: regUser._id})//delete user's comment by checking the comment author's id.
            await Reply.deleteMany({author: regUser._id})//deletes user's replies
            await User.findByIdAndDelete(req.params.id)//delete the user
            res.status(200).json("User has been deleted")
        } catch(err){
            res.status(500).json(err) //this handles the error if there is one from the server
        }
    }catch(err){
        res.status(404).json("User not found")
    }


  }else{
     res.status(401).json("You do not have the permission")
  }

   }

   
       


 });

当我在邮递员上尝试这段代码时,它一直在加载并且没有发送任何东西。

我知道我没有正确编写函数。请为我提供任何帮助以使我能够实现这一目标。谢谢

【问题讨论】:

    标签: node.js


    【解决方案1】:

    我尝试对 API 的请求正文进行逆向工程。 我认为是这样的:

    {
        body: {
          userId: string
          userName: string
        }
        params: {
          id: string
        }
    }
    

    因此,尝试对每个值的用途进行逆向工程:

    • params-id 显然只是包含在 URL 中的参数。所以,这就是您要删除的用户的 ID。

    那么,你体内的userIduserName是什么?

    安全问题

    从您的代码来看,userName 和/或userId 指的是登录并执行操作的用户。当然,这不安全。

    您知道每个用户都可以在其网络浏览器中按 F12 并查看所有输入/输出请求。修改它们并输入不同用户的 ID 真的很容易。因此,您当然需要更多的安全性。

    您需要的是跟踪登录用户的“上下文”。例如有时登录用户的整个用户对象会添加到req.context.me

    我搜索了一个说明这一点的教程,并找到了this 一个。这不完全是我的意思,但它是相似的。他们将userId 存储在req 对象上。将其作为req.userId 提供。

    除了安全

    写完这一切,你想要做的可能是以下。

    router.delete("/:id", async(req, res) => {
    
      const loggedInUser = await User.findById(req.body.userId);
      if (loggedInUser && loggedInUser.role === "admin") {
        try {
          const regUser = await User.findById(req.params.id);
          if (regUser == null) {
            throw new Error("user not found");
          }
          
          await Post.deleteMany({
            username: regUser._id
          }) //deleting user posts once the username matches with the variable user object .username
          await Comment.deleteMany({
            author: regUser._id
          }) //delete user's comment by checking the comment author's id.
          await Reply.deleteMany({
            author: regUser._id
          }) //deletes user's replies
          await User.findByIdAndDelete(req.params.id) //delete the user
          res.status(200).json("User has been deleted")
        } catch (err) {
          res.status(500).json(err) //this handles the error if there is one from the server
        }
      } else {
        res.status(401).json("You do not have the permission")
      }
    }
    

    如您所见,您不需要用户名。

    DELETE 不支持正文

    DELETE 是否可以有正文实际上是一个讨论点。有些客户端/服务器支持它,有些则不支持。您可以在此处找到更多相关信息:

    body is empty when parsing DELETE request with express and body-parser

    再次,这意味着您真的不应该通过正文传递登录用户。

    【讨论】:

    • 非常感谢。我真诚而深刻地感谢您投入的时间和精力,在安全等重要问题上对我进行了教育。我试过你在邮递员上写的这段代码,但我不断收到“你没有权限”。 url id 是我要删除的用户的 id。然后在正文中,我提供了要删除的管理员的 ID。我做对了吗?
    • @kinhs 假设您使用了我在上面发布的修改后的代码,这意味着 userId 没有在正文中正确发送,或者它不存在于数据库中,或者它有不同的作用。找出发生了什么的最简单方法是添加一行console.log(req.body.userId)。在if (loggedInUser && 行之前,您应该添加一个console.log(loggedInUser ? 'role:' + loggedInUser.role ': 'user not found' )
    • PS:添加了一个教程链接,该链接展示了如何从 JWT 令牌中扣除 req.userId
    • 是的,我正在使用您修改的代码。console.log(req.body.userId) 返回未定义。从你所说的安全性来看,你的意思是我应该避免使用 req.body.username 而使用 req.body.userId ,对吗?因为我在另一个地方使用了 req.body.userId。我想了解,以便我可以返回代码进行修改。谢谢
    • @kinhs ...在这种情况下。您可能遇到了“DELETE 不支持正文”问题。 (我添加了一个链接)。
    猜你喜欢
    • 1970-01-01
    • 2021-05-23
    • 2020-09-08
    • 1970-01-01
    • 1970-01-01
    • 2018-04-23
    • 1970-01-01
    • 1970-01-01
    • 2018-07-17
    相关资源
    最近更新 更多