0

0

如何在用户模式中向好友数组添加用户

DDD

DDD

发布时间:2025-09-28 16:22:00

|

350人浏览过

|

来源于php中文网

原创

如何在用户模式中向好友数组添加用户

本文旨在指导开发者如何在用户接受好友请求后,将其信息添加到对方用户模式的 friends 数组中。文章将讨论避免前端篡改用户ID的措施,并通过 FriendRequest 模型查询好友列表,同时也会介绍如何在接受好友请求时更新用户模式,并强调使用事务以保证数据一致性的重要性。

确保用户ID的安全性

在处理好友请求时,直接从前端获取发送者(sender)ID存在安全风险。恶意用户可以通过修改HTML来伪造发送者ID,从而导致数据不一致或潜在的安全问题。为了避免这种情况,应该从服务器端的会话或身份验证中间件中获取当前用户的ID。

例如,前端表单可以只包含接收者(receiver)的ID:

后端路由处理程序中,使用身份验证中间件提供的当前用户ID作为发送者:

router.post("/requests", (req, res) => {
  const { receiver } = req.body;

  FriendRequest.create({
    sender: req.user._id, // 从身份验证中间件获取当前用户ID
    receiver
  }).then(() => {
    res.status(204).send();
  }).catch((error) => {
    res.status(500).send("Error sending friend request");
  });
});

这里假设 req.user._id 包含了经过身份验证的用户的ID。你需要根据你使用的身份验证方法调整这部分代码。

通过 FriendRequest 模型查询好友列表

一种更优雅的方式是避免在 User 模型中显式维护 friends 数组。相反,可以通过查询 FriendRequest 模型来获取好友列表。这种方法利用了 FriendRequest 模型中已经存在的 sender 和 status 字段。

例如,要获取当前用户的所有已接受的好友,可以使用以下查询:

FriendRequest
  .find({sender: req.user._id, status: 'accepted'})
  .then((listOfFriends)=>{
    console.log(listOfFriends);
  })
  .catch((e)=>{
    // handle error
  })

这种方法的优点是避免了数据冗余,并且在好友关系发生变化时,只需要更新 FriendRequest 模型即可。

I-Shop购物系统
I-Shop购物系统

部分功能简介:商品收藏夹功能热门商品最新商品分级价格功能自选风格打印结算页面内部短信箱商品评论增加上一商品,下一商品功能增强商家提示功能友情链接用户在线统计用户来访统计用户来访信息用户积分功能广告设置用户组分类邮件系统后台实现更新用户数据系统图片设置模板管理CSS风格管理申诉内容过滤功能用户注册过滤特征字符IP库管理及来访限制及管理压缩,恢复,备份数据库功能上传文件管理商品类别管理商品添加/修改/

下载

更新用户模式中的 friends 数组 (谨慎使用)

如果仍然需要在 User 模型中显式维护 friends 数组,则需要在接受好友请求时更新这两个用户的 friends 数组。

router.post("/requests/:id/accept", async (req, res) => {
  try {
    const request = await FriendRequest.findById(req.params.id);
    request.status = "accepted";
    await request.save();

    const currentUser = await User.findById(req.user._id); // 获取当前用户
    const otherUser = await User.findById(request.receiver); // 获取接收者用户

    currentUser.friends.push(request.receiver);
    otherUser.friends.push(req.user._id);

    await currentUser.save();
    await otherUser.save();

    res.redirect("/requests");
  } catch (error) {
    // 处理错误
    console.error("Error accepting friend request:", error);
    res.status(500).send("Error accepting friend request");
  }
});

注意事项:使用事务

在更新多个集合时,务必使用数据库事务来确保数据一致性。如果在更新 FriendRequest 模型后,更新 User 模型失败,则可能导致数据不一致。

以下是如何使用 Mongoose 事务的示例:

const mongoose = require('mongoose');

router.post("/requests/:id/accept", async (req, res) => {
  const session = await mongoose.startSession();
  session.startTransaction();
  try {
    const request = await FriendRequest.findById(req.params.id).session(session);
    request.status = "accepted";
    await request.save({ session });

    const currentUser = await User.findById(req.user._id).session(session); // 获取当前用户
    const otherUser = await User.findById(request.receiver).session(session); // 获取接收者用户

    currentUser.friends.push(request.receiver);
    otherUser.friends.push(req.user._id);

    await currentUser.save({ session });
    await otherUser.save({ session });

    await session.commitTransaction();
    session.endSession();

    res.redirect("/requests");
  } catch (error) {
    await session.abortTransaction();
    session.endSession();
    // 处理错误
    console.error("Error accepting friend request:", error);
    res.status(500).send("Error accepting friend request");
  }
});

在这个示例中,mongoose.startSession() 创建一个新的会话,session.startTransaction() 启动事务。所有的数据库操作都通过 .session(session) 传递会话对象。如果所有操作都成功,则 session.commitTransaction() 提交事务;否则,session.abortTransaction() 回滚事务,撤销所有更改。

总结

在处理好友请求时,务必注意用户ID的安全性,并考虑使用 FriendRequest 模型查询好友列表,以避免数据冗余。如果需要在 User 模型中显式维护 friends 数组,则务必使用数据库事务来确保数据一致性。选择哪种方法取决于你的具体需求和对数据一致性的要求。

相关专题

更多
什么是中间件
什么是中间件

中间件是一种软件组件,充当不兼容组件之间的桥梁,提供额外服务,例如集成异构系统、提供常用服务、提高应用程序性能,以及简化应用程序开发。想了解更多中间件的相关内容,可以阅读本专题下面的文章。

178

2024.05.11

Golang 中间件开发与微服务架构
Golang 中间件开发与微服务架构

本专题系统讲解 Golang 在微服务架构中的中间件开发,包括日志处理、限流与熔断、认证与授权、服务监控、API 网关设计等常见中间件功能的实现。通过实战项目,帮助开发者理解如何使用 Go 编写高效、可扩展的中间件组件,并在微服务环境中进行灵活部署与管理。

213

2025.12.18

html版权符号
html版权符号

html版权符号是“©”,可以在html源文件中直接输入或者从word中复制粘贴过来,php中文网还为大家带来html的相关下载资源、相关课程以及相关文章等内容,供大家免费下载使用。

616

2023.06.14

html在线编辑器
html在线编辑器

html在线编辑器是用于在线编辑的工具,编辑的内容是基于HTML的文档。它经常被应用于留言板留言、论坛发贴、Blog编写日志或等需要用户输入普通HTML的地方,是Web应用的常用模块之一。php中文网为大家带来了html在线编辑器的相关教程、以及相关文章等内容,供大家免费下载使用。

655

2023.06.21

html网页制作
html网页制作

html网页制作是指使用超文本标记语言来设计和创建网页的过程,html是一种标记语言,它使用标记来描述文档结构和语义,并定义了网页中的各种元素和内容的呈现方式。本专题为大家提供html网页制作的相关的文章、下载、课程内容,供大家免费下载体验。

470

2023.07.31

html空格
html空格

html空格是一种用于在网页中添加间隔和对齐文本的特殊字符,被用于在网页中插入额外的空间,以改变元素之间的排列和对齐方式。本专题为大家提供html空格的相关的文章、下载、课程内容,供大家免费下载体验。

245

2023.08.01

html是什么
html是什么

HTML是一种标准标记语言,用于创建和呈现网页的结构和内容,是互联网发展的基石,为网页开发提供了丰富的功能和灵活性。本专题为大家提供html相关的各种文章、以及下载和课程。

2895

2023.08.11

html字体大小怎么设置
html字体大小怎么设置

在网页设计中,字体大小的选择是至关重要的。合理的字体大小不仅可以提升网页的可读性,还能够影响用户对网页整体布局的感知。php中文网将介绍一些常用的方法和技巧,帮助您在HTML中设置合适的字体大小。

505

2023.08.11

PS使用蒙版相关教程
PS使用蒙版相关教程

本专题整合了ps使用蒙版相关教程,阅读专题下面的文章了解更多详细内容。

23

2026.01.19

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Bootstrap 5教程
Bootstrap 5教程

共46课时 | 2.9万人学习

AngularJS教程
AngularJS教程

共24课时 | 2.7万人学习

CSS教程
CSS教程

共754课时 | 20.9万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号