node.js - Mongoose 关注/关注者

标签 node.js mongodb express mongoose

我正在尝试为 nodejs/mongoose 驱动的网站添加关注/关注者功能。我在使用以下方法正确存储 ID 时遇到问题。不太确定出了什么问题,但它似乎只将 ID 正确保存到以下部分,但没有更新第一部分的关注者。

我知道如果将用户 ID 直接传递给 post 请求会很容易,但我认为将用户 ID 存储在前端是一种安全问题,因此仅使用用户名来获取 ID 会更好。

// Handles the post request for following a user
router.post('/follow-user', function(req, res, next) {

  // First, find the user from the user page being viewed
  User.findOne({ username: req.body.username }, function(err, user) {

    // Add to users followers with ID of the logged in user
    user.followers = req.user._id;

    // Create variable for user from page being viewed
    var followedUser = user._id;

    // Save followers data to user
    user.save();

    // Secondly, find the user account for the logged in user
    User.findOne({ username: req.user.username }, function(err, user) {

      // Add the user ID from the users profile the follow button was clicked
      user.following = followedUser;

      // Save following data to user
      user.save();
    });
  });
});

用户模型看起来是这样的

var userSchema = new Schema({
  username: { type: String, required: true, unique: true },
  password: { type: String, required: true },
  email: { type: String, required: true },
  avatar: { type: String },
  bio: { type: String },
  following: [{ type: Schema.ObjectId, ref: 'User' }],
  followers: [{ type: Schema.ObjectId, ref: 'User' }],
});

对此的任何见解将不胜感激。

最佳答案

我通过设置两条路由而不是一条路由,成功地在 Node REST API 上实现了follow/unfollow 功能:

对于关注请求:

  1. 我检查 ID 是否有效
  2. 我会检查您的 ID 是否与您要关注的用户的 ID 不匹配
  3. 我将您要关注的用户 ID 添加到以下数组中
  4. 我将您的 ID 添加到您想要关注的用户的 followers 数组中

对于取消关注请求:

  1. 我检查 ID 是否有效
  2. 我会检查您的 ID 是否与您想要取消关注的用户的 ID 不匹配
  3. 我从以下数组中删除了您想要取消关注的用户的 ID
  4. 我从您想要取消关注的用户的 followers 数组中删除您的 ID

authenticate is my custom middleware

id params is the ID of the user you're trying to follow/unfollow

res.user is returned from the "authenticate" middleware, please do not my answer.

router.patch('/follow/:id', authenticate, async (req, res) => {
    try {
        const id = new ObjectID(req.params.id)

        // check if the id is a valid one
        if (!ObjectID.isValid(req.params.id)) {
            return res.status(404).json({ error: 'Invalid ID' })
        }

        // check if your id doesn't match the id of the user you want to follow
        if (res.user._id === req.params.id) {
            return res.status(400).json({ error: 'You cannot follow yourself' })
        }

        // add the id of the user you want to follow in following array
        const query = {
            _id: res.user._id,
            following: { $not: { $elemMatch: { $eq: id } } }
        }

        const update = {
            $addToSet: { following: id }
        }

        const updated = await User.updateOne(query, update)

        // add your id to the followers array of the user you want to follow
        const secondQuery = {
            _id: id,
            followers: { $not: { $elemMatch: { $eq: res.user._id } } }
        }

        const secondUpdate = {
            $addToSet: { followers: res.user._id }
        }

        const secondUpdated = await User.updateOne(secondQuery, secondUpdate)

        if (!updated || !secondUpdated) {
            return res.status(404).json({ error: 'Unable to follow that user' })
        }

        res.status(200).json(update)
    } catch (err) {
        res.status(400).send({ error: err.message })
    }
})

router.patch('/unfollow/:id', authenticate, async (req, res) => {
    try {
        const { id } = req.params

        // check if the id is a valid one
        if (!ObjectID.isValid(id)) {
            return res.status(404).json({ error: 'Invalid ID' })
        }

        // check if your id doesn't match the id of the user you want to unfollow
        if (res.user._id === id) {
            return res.status(400).json({ error: 'You cannot unfollow yourself' })
        }

        // remove the id of the user you want to unfollow from following array
        const query = {
            _id: res.user._id,
            following: { $elemMatch: { $eq: id } }
        }

        const update = {
            $pull: { following: id }
        }

        const updated = await User.updateOne(query, update)

        // remove your id from the followers array of the user you want to unfollow
        const secondQuery = {
            _id: id,
            followers: { $elemMatch: { $eq: res.user._id } }
        }

        const secondUpdate = {
            $pull: { followers: res.user._id }
        }

        const secondUpdated = await User.updateOne(secondQuery, secondUpdate)

        if (!updated || !secondUpdated) {
            return res.status(404).json({ error: 'Unable to unfollow that user' })
        }

        res.status(200).json(update)
    } catch (err) {
        res.status(400).send({ error: err.message })
    }
})

关于node.js - Mongoose 关注/关注者,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43463205/

相关文章:

node.js - 错误: Cannot query across one-to-many for property TypeORM

java - Mongo 数据库,选择 * WHERE id = 3 AND id = 4

javascript - Express/Mongoose 项目中的 HTTP Get 和 Post 请求中缺少内容

node.js - Angular.js 可以在脚本标签中的 Jade 模板中进行插值吗?

node.js - 如何在 express 权限中使用 "cookie-parser"以及 socket.io 中的 cookie 在哪里?

node.js - 如何在 Ubuntu 15.10 上通过命令安装 nodejs

ruby-on-rails - EventMachine 与 Node.js

MongoDB 聚合 - $sum 参数

javascript - 编写不知道其在堆栈中位置的中间件

javascript - CORS 策略 : Response to preflight request doesn't pass access control check