You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何仅用2个集合实现MongoDB用户/角色可访问数据限制

MongoDB班级用户权限控制实现方案

1. 集合结构设计

严格按照要求仅使用2个集合,结构设计如下:

班级集合 classes

存储所有班级公共信息:

{
  "_id": ObjectId("60d21b4c7f8a9b0c1d2e3f4a"),
  "class_name": "高二3班",
  "create_time": ISODate("2023-09-01T00:00:00Z"),
  "head_teacher": "张老师"
}

字段说明:

  • _id:MongoDB默认生成的唯一班级ID,作为和用户关联的外键
  • 其余字段可根据业务需要自行扩展

用户集合 users

存储所有用户的个人信息,每个用户唯一绑定一个班级:

{
  "_id": ObjectId("60d21b9a7f8a9b0c1d2e3f4b"),
  "student_id": "20220301",
  "name": "李四",
  "class_id": ObjectId("60d21b4c7f8a9b0c1d2e3f4a"),
  "password_hash": "$2a$10$...",
  "contact": "13xxxxxxxxx"
}

字段说明:

  • class_id 必须和 classes._id 一一对应,是权限控制的核心关联字段
  • 禁止存储明文密码,所有密码必须做哈希加密处理

2. 权限控制实现

最优方案:仅允许用户查看自身信息

用户登录后,后端直接固定查询条件为当前登录用户的_id,禁止不带该条件查询users集合:

// 示例查询语句,userId为当前登录用户的_id
db.users.find(
  { _id: ObjectId(userId) },
  { password_hash: 0 } // 投影过滤敏感字段,不返回密码哈希
)

注意:查询条件必须由后端从登录态直接获取,禁止前端传入自定义查询条件,避免越权。

扩展方案:允许查看同班级所有用户信息

如果需要开放同班级用户查看权限,后端固定查询条件为当前登录用户的class_id:

// 示例查询语句,classId为当前登录用户的class_id
db.users.find(
  { class_id: ObjectId(classId) },
  { password_hash: 0, contact: 0 } // 可根据需要过滤同班级用户的敏感字段
)

校验规则:如果业务需要允许用户传入班级ID查询,必须先校验传入的classId和当前登录用户的classId完全一致,否则直接拒绝请求。

3. 数据库层权限加固方案(无需业务层重复编码)

如果不想在业务代码中重复写权限逻辑,可以直接用MongoDB自带的角色权限控制实现自动过滤:

  1. 为每个班级创建专属只读角色,限制该角色仅能查询users集合中class_id匹配的文档:
db.createRole({
  role: "class_60d21b4c7f8a9b0c1d2e3f4a_readonly",
  privileges: [
    {
      resource: { db: "your_db_name", collection: "users" },
      actions: ["find"],
      condition: { class_id: ObjectId("60d21b4c7f8a9b0c1d2e3f4a") }
    }
  ],
  roles: []
})
  1. 用户登录成功后,为其分配对应班级的角色,后续用户发起的查询会被MongoDB自动过滤不符合权限的文档,无需业务层额外加条件。

内容的提问来源于stack exchange,提问作者CCstyle

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.07 00:09:04