Web安全
基础漏洞
01前端基础【HTML】
02前端基础【CSS】
03后端基础【PHP速通】
04后端基础【PHP面向对象】
05MySQL基础操作
06前后端联动【代码练习】
07SQL注入【1】
07SQL 注入【2】
08SQL注入 Labs
08SQL注入速查表
09XSS
09跨站脚本攻击【XSS】
09XSS Labs
10跨站请求伪造【CSRF】
11服务器端请求伪造【SSRF】
12XML 外部实体注入【XXE】
13代码执行漏洞
14命令执行漏洞
15文件包含漏洞
16文件上传漏洞
17反序列化漏洞
18业务逻辑漏洞
19未授权访问漏洞集合
20跨源资源共享【CORS】
21SSTI模板注入
22并发漏洞
23点击劫持【Clickjacking 】
24请求走私
25路径遍历
26访问控制
27身份验证漏洞
28WebSocket
29Web缓存中毒
30HTTP 主机头攻击
31信息泄露漏洞
32原型污染
33NoSQL注入
API 安全
01web应用程序
02HTTP协议
03API概述
04分类类型
05交换格式
06身份验证
07常见API漏洞
08crAPI靶场
09JWT
10OAuth 2.0身份验证
11GraphQL【1】
11GraphQL【2】
12DVGA靶场
13服务器端参数污染
14API文档
15API Labs
16OAuth Labs
17GraphQL API Labs
18JWT Labs
小程序
小程序抓包
数据库
MySQL
Oracle
MongoDB
Redis
PostgreSQL
SQL server
中间件
Nginx
Apache HTTP Server
IIS
Tomcat
框架
ThinkPHP
Spring
Spring Boot
Django
访问控制
-
+
首页
MongoDB
 ## 概述 MongoDB 是一款**文档型 NoSQL 数据库**,由 MongoDB Inc. 开发,旨在解决传统关系型数据库(如 MySQL、Oracle)在 “灵活 schema、高并发、海量数据存储” 场景下的局限性。 MongoDB 以 **BSON(Binary JSON)** 作为数据存储格式(支持更多数据类型,如日期、二进制、数组等),适用于电商用户画像、日志分析、物联网数据、内容管理系统等场景。 **默认端口号**:27017;**官网地址**:https://www.mongodb.com。 ## 特性 MongoDB 区别于关系型数据库的核心优势的在于 “灵活性” 与 “可扩展性”,具体特性如下: **1. 文档模型(无固定 Schema)** 数据以 “文档” 为单位存储(类似 JSON 对象),集合(Collection)无需预先定义字段结构,同一集合中可存储字段不同的文档。例如:同一 users 集合中,可同时存储 “有手机号的用户” 和 “无手机号的用户”,无需修改表结构。 **2. 灵活模式**:同一个集合中的文档不需要具有相同的字段集。你可以随时为文档添加新字段,而无需像关系型数据库那样执行 ALTER TABLE 操作。这大大加快了开发迭代速度。 **3. 高性能**: - 嵌入式数据模型:通过嵌套文档减少昂贵的表连接(JOIN)操作。 - 索引支持:支持丰富的索引类型(单字段、复合、多键、文本、地理空间、哈希等),并可自动在后台创建索引以提升查询速度。 - 内存映射:通过内存映射文件将磁盘 IO 操作转换为内存操作,效率极高。 **4. 高可用性**:通过复制集 (Replica Set) 提供自动故障转移。一个复制集包含多个数据副本(主节点、从节点),主节点宕机后,从节点会自动选举出新的主节点,服务不间断。 **5. 水平扩展 (分片)**:通过 分片 (Sharding) 将数据分布式地存储在多台机器上,以处理巨大的数据量和吞吐量。应用程序几乎感知不到后端的分片细节。 **6. 丰富的查询语言**:支持 CRUD 操作、数据聚合、文本搜索、地理空间查询等几乎所有类型的查询。 **6. 支持事务**:从 MongoDB 4.0 开始支持 “多文档事务”(副本集架构),4.2 版本扩展到分片集群,满足金融、电商等对事务一致性有要求的场景。 ## 与MySQL区别 | 特性 | 关系型数据库 (MySQL) | MongoDB (NoSQL) | | ----------------- | ----------------------------- | ------------------------------------- | | **数据模型** | 表 (Table) 和行 (Row) | 集合 (Collection) 和文档 (Document) | | **模式 (Schema)** | 固定结构,预定义列 | 动态模式(无模式),文档结构可变化 | | **查询语言** | SQL (SELECT, UPDATE, DELETE) | 丰富的查询语言 (方法链、操作符) | | **扩展性** | 垂直扩展 (Scale-up),主从复制 | 水平扩展 (Scale-out),分片 (Sharding) | | **事务** | 完整支持 ACID 事务 | 从 4.0 版本开始支持多文档 ACID 事务 | ## 基本概念 **数据库 (Database)**:一个 MongoDB 实例可以承载多个数据库。 **集合 (Collection)**:相当于关系型数据库中的**表**,是一组文档的集合。 **文档 (Document)**:相当于关系型数据库中的**行**,是数据的基本单位,是一个键值对集合,采用 BSON 格式。 ## 系统数据库 MongoDB 安装后会自动创建 **4 个系统默认数据库**,用户无需手动创建,且各有特定用途: | 数据库名称 | 核心作用 | 注意事项 | | ---------- | -------------------------- | ------------------------------------------------------------ | | admin | 管理员数据库(最高权限) | 存储数据库用户、角色权限;若用户在 admin 库拥有 root 角色,可管理所有数据库 | | local | 本地数据库(不复制) | 存储当前节点的本地数据(如副本集配置的本地日志),**不会同步到其他副本集节点**,删除无风险 | | config | 分片集群配置库,配置数据库 | 仅在分片集群中存在,存储分片集群的节点、分片、数据分布等配置信息,禁止手动修改 | | test | 默认用户数据库 | 若用户未指定数据库(如直接输入 mongo 连接),默认使用 test 库;可随意操作,适合测试 | ## 安装 使用docker安装 mangodb 数据库。 拉去最新版本的数据库: ```bash # 拉取最新版本(推荐生产环境指定具体版本,如 mongo:6.0) docker pull mongo:latest ``` ```bash C:\Users\root>docker pull mongo:latest latest: Pulling from library/mongo 76249c7cd503: Pull complete a6ccce675b91: Pull complete 4ba0ed20cdee: Pull complete da3134f8e686: Pull complete a20c427c2ead: Pull complete 5777c09b20e7: Pull complete 930dfd6340eb: Pull complete 96b1c4e20b5d: Pull complete Digest: sha256:7acbcf333608e67bc140821d31144dcc579e1479d12d5292d67c74b470082a6a Status: Downloaded newer image for mongo:latest docker.io/library/mongo:latest C:\Users\root>docker images REPOSITORY TAG IMAGE ID CREATED SIZE mongo latest eff94de2e019 2 days ago 909MB C:\Users\root> ``` ## 创建并启动容器 核心需求:**端口映射**(主机可访问)、**权限认证**(设置管理员密码)。 ```bash docker run -d # 后台运行 --name mongo \ # 容器名称(自定义,如 mongo-db) -p 27017:27017 \ # 端口映射:主机27017 → 容器27017(MongoDB默认端口) -e MONGO_INITDB_ROOT_USERNAME=admin \ # 初始化root用户(管理员) -e MONGO_INITDB_ROOT_PASSWORD=123456 \ # 管理员密码(自定义,生产环境用强密码) mongo:latest # 使用的镜像名称 ``` ```bash C:\Users\root>docker run -d --name mongo -p 27017:27017 -e MONGO_INITDB_ROOT_USERNAME=admin -e MONGO_INITDB_ROOT_PASSWORD=123456 mongo:latest 8cebf272299c6afbc6fad74096499f7a7bcd0ad3a934f1b82c3440ca6b3d8355 C:\Users\root>docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 8cebf272299c mongo:latest "docker-entrypoint.s…" 6 seconds ago Up 5 seconds 0.0.0.0:27017->27017/tcp, [::]:27017->27017/tcp mongo ``` **第一种方式:**使用【Navicat】外部数据库连接工具进行连接(官网免费版下载地址:https://www.navicat.com.cn/download/navicat-premium-lite)。  连接方式: | **模式** | **架构特点** | **数据分布** | **高可用性** | **扩展性** | **适用场景** | | ----------------- | ------------------------------------------------------------ | -------------------- | ---------------------- | -------------------------- | ---------------------------------------------- | | **Standalone** | 单个 MongoDB 实例,无复制或分片 | 数据集中存储 | 无(单点故障) | 无法扩展(垂直扩展) | 开发测试、小型应用(如个人博客) | | **Replica Set** | 多个节点组成的集群,包含一个主节点(Primary)和多个从节点(Secondary),自动故障转移 | 数据在所有节点上复制 | 高(自动选举新主节点) | 读扩展(从节点分担读压力) | 生产环境、需要高可用性的业务(如电商订单系统) | | **Shard Cluster** | 数据分散存储在多个分片(Shard)上,通过路由进程(mongos)协调访问 | 数据按分片键水平分布 | 高(每个分片是副本集) | 水平扩展(按需添加分片) | 海量数据、高吞吐量场景(如社交媒体、物联网) |  验证方式: | **验证类型** | **安全性** | **适用场景** | **配置复杂度** | **Navicat 版本支持** | **典型问题** | | ------------ | ---------- | ------------------------------------------------------------ | -------------- | ------------------------ | ---------------------------------------------------------- | | **None** | 无 | 本地开发测试、未启用认证的 MongoDB 实例 | ★☆☆☆☆ | 全版本 | 生产环境禁用,易受未授权访问攻击 | | **Password** | 中 | 中小型项目、需简单数据库级认证的场景 | ★★☆☆☆ | 全版本 | 密码强度不足时易被破解,需结合 SSL/TLS 加密传输 | | **LDAP** | 高 | 企业环境集成现有 LDAP 目录服务(如 Active Directory),统一用户管理 | ★★★★☆ | 企业版 / 旗舰版 | LDAP 服务器不可达、用户搜索基础配置错误 | | **Kerberos** | 极高 | 跨平台分布式系统、需单点登录(SSO)的大型企业应用(如金融、医疗) | ★★★★★ | 仅企业版 | 密钥分发中心(KDC)配置错误、服务主体名称(SPN)不匹配 | | **X.509** | 极高 | 金融、政务等高安全要求场景,需双向证书验证的加密通信 | ★★★★☆ | 全版本(需证书文件支持) | 证书链不完整、客户端证书未导入信任库、证书过期或域名不匹配 |  **第二种方式:**容器内连接。 ```bash C:\Users\root>docker exec -it 8cebf272299c bash root@8cebf272299c:/# mongosh -u admin -p Enter password: ****** Current Mongosh Log ID: 68c28faadf0d1d729cfa334f Connecting to: mongodb://<credentials>@127.0.0.1:27017/?directConnection=true&serverSelectionTimeoutMS=2000&appName=mongosh+2.5.7 Using MongoDB: 8.0.13 Using Mongosh: 2.5.7 For mongosh info see: https://www.mongodb.com/docs/mongodb-shell/ To help improve our products, anonymous usage data is collected and sent to MongoDB periodically (https://www.mongodb.com/legal/privacy-policy). You can opt-out by running the disableTelemetry() command. ------ The server generated these startup warnings when booting 2025-09-11T08:40:31.012+00:00: Using the XFS filesystem is strongly recommended with the WiredTiger storage engine. See http://dochub.mongodb.org/core/prodnotes-filesystem 2025-09-11T08:40:31.395+00:00: For customers running the current memory allocator, we suggest changing the contents of the following sysfsFile 2025-09-11T08:40:31.395+00:00: For customers running the current memory allocator, we suggest changing the contents of the following sysfsFile 2025-09-11T08:40:31.395+00:00: We suggest setting the contents of sysfsFile to 0. 2025-09-11T08:40:31.395+00:00: vm.max_map_count is too low 2025-09-11T08:40:31.395+00:00: We suggest setting swappiness to 0 or 1, as swapping can cause performance problems. ------ test> ``` 连接成功后,终端会显示 test>(默认进入 test 数据库),表示已进入 MongoDB 交互环境。 ## 数据库操作 MongoDB 中,数据存储层级为:**数据库(Database)→ 集合(Collection)→ 文档(Document)**,类似 “文件夹→子文件夹→文件”。 MongoDB 无需 “显式创建数据库”,**切换到不存在的数据库后,插入数据即自动创建**。 | 操作目标 | 命令示例 | 解释 | | ----------------- | -------------------------- | ------------------------------------------------------------ | | 切换 / 创建数据库 | use mydb | 若 mydb 存在则切换,不存在则在插入数据时创建(仅 use 不会创建) | | 查看当前数据库 | db | 输出当前所在数据库(如 mydb) | | 查看所有数据库 | show dbs 或 show databases | 仅显示 “有数据的数据库”(空数据库不会显示) | | 删除当前数据库 | db.dropDatabase() | 谨慎操作!删除当前所在数据库的所有数据和集合,返回 { "dropped": "mydb", "ok": 1 } 表示成功 | ```sql test> show dbs admin 100.00 KiB config 60.00 KiB local 72.00 KiB test> db test ``` ## 集合操作 集合(Collection)类似关系型数据库的 “表”,同样支持显式创建和隐式创建(插入文档时自动创建)。 **1. 创建集合(显式)** ```javascript # 基础创建(无参数) db.createCollection("users") # 带参数创建(如“固定大小集合”,适合日志存储) db.createCollection("logs", { capped: true, // 启用固定大小 size: 1024*1024, // 集合最大容量(1MB) max: 1000 // 最多存储 1000 条文档(达到后覆盖旧文档) }) ``` ```sql test> db.createCollection("users") { ok: 1 } test> db.createCollection("logs", { ... capped: true, ... size: 1024*1024, ... max: 1000 ... }) { ok: 1 } test> ``` **2. 查看与切换集合** ```javascript # 查看当前数据库的所有集合 show collections 或 show tables # 切换集合(后续操作默认针对该集合,无需“use”,直接通过 db.集合名 操作) db.users // 切换到 users 集合 ``` ```sql test> show collections logs users test> show tables logs users test> db.users test.users test> ``` **3. 删除集合** ```javascript # 删除指定集合(如删除 users 集合) db.users.drop() # 返回结果:true 表示删除成功,false 表示集合不存在 ``` ## 文档操作 文档(Document)是 MongoDB 最小数据单元,格式为 BSON(类似 JSON,支持 int、date、array 等类型)。 常用操作包括 **插入(Create)、查询(Read)、更新(Update)、删除(Delete)**。 **1. 插入文档** MongoDB 提供 insertOne()(单文档)和 insertMany()(多文档)两种方法,支持批量插入。 示例 1:插入单个文档(insertOne)。 ```javascript db.users.insertOne({ name: "张三", age: 25, email: "zhangsan@example.com", hobbies: ["篮球", "游戏"], // 数组类型 address: { // 嵌套文档(类似 JSON 嵌套) province: "广东", city: "深圳" }, createTime: new Date() // 日期类型(BSON 特有) }) ``` ```sql test> db.users.insertOne({ ... name: "张三", ... age: 25, ... email: "zhangsan@example.com", ... hobbies: ["篮球", "游戏"], ... address: { ... province: "广东", ... city: "深圳" ... }, ... createTime: new Date() ... }) { acknowledged: true, insertedId: ObjectId('68c291dcdf0d1d729cfa3350') } test> ``` 返回结果:包含插入文档的 _id(MongoDB 自动生成的唯一标识,类似主键) ```sql { acknowledged: true, insertedId: ObjectId('68c291dcdf0d1d729cfa3350') } ``` 示例 2:插入多个文档(insertMany)。 ```javascript db.users.insertMany([ { name: "李四", age: 30, email: "lisi@example.com", hobbies: ["读书", "跑步"], createTime: new Date() }, { name: "王五", age: 28, email: "wangwu@example.com", hobbies: ["旅行", "摄影"], address: { province: "浙江", city: "杭州" }, createTime: new Date() } ]) ``` ```sql test> db.users.insertMany([ ... { ... name: "李四", ... age: 30, ... email: "lisi@example.com", ... hobbies: ["读书", "跑步"], ... createTime: new Date() ... }, ... { ... name: "王五", ... age: 28, ... email: "wangwu@example.com", ... hobbies: ["旅行", "摄影"], ... address: { province: "浙江", city: "杭州" }, ... createTime: new Date() ... } ... ]) ... { acknowledged: true, insertedIds: { '0': ObjectId('68c29215df0d1d729cfa3351'), '1': ObjectId('68c29215df0d1d729cfa3352') } } ``` **2. 文档查询** 查询是 MongoDB 的核心能力,支持简单查询、条件过滤、投影(只返回指定字段)、排序、分页等,核心方法为 find() 和 findOne()。 | 查询需求 | 命令示例 | 解释 | | ---------------------- | ------------------------------------------------------------ | ------------------------------------------------------------ | | 查询所有文档 | db.users.find() 或 db.users.find().pretty() | pretty() 用于格式化输出(可读性更高),不加则紧凑显示 | | 查询单个文档(第一条) | db.users.findOne({ age: 25 }) | 返回满足条件的**第一条文档**(自动忽略其他匹配项),无需 pretty() | | 条件查询(等于) | db.users.find({ name: "张三" }) | 查询 name 字段等于 “张三” 的文档(BSON 中键值对默认是 “等于” 判断) | | 条件查询(范围) | db.users.find({ age: { $gt: 25, $lte: 30 } }) | $gt = 大于,$lte = 小于等于,查询年龄 “>25 且 ≤30” 的文档 | | 条件查询(数组包含) | db.users.find({ hobbies: "篮球" }) | 查询 hobbies 数组中**包含 “篮球”** 的文档(不管数组其他元素) | | 条件查询(逻辑或) | db.users.find({ $or: [ { age: 25 }, { city: "深圳" } ] }) | 查询 “年龄 = 25”**或**“城市 = 深圳” 的文档($and 用于逻辑与,默认是与) | | 投影(只返回指定字段) | db.users.find({ age: { $gt: 25 } }, { name: 1, age: 1, _id: 0 }) | 1 表示返回该字段,0 表示不返回(_id 默认返回,需显式设为 0 隐藏) | | 排序(升序 / 降序) | db.users.find().sort({ age: 1 }) 或 db.users.find().sort({ age: -1 }) | 1 = 升序,-1 = 降序(按年龄排序) | | 分页(跳过 + 限制) | db.users.find().skip(1).limit(2) | skip(1) 跳过前 1 条,limit(2) 只返回 2 条(实现第 2-3 条数据分页) | ```sql test> db.users.find() [ { _id: ObjectId('68c291dcdf0d1d729cfa3350'), name: '张三', age: 25, email: 'zhangsan@example.com', hobbies: [ '篮球', '游戏' ], address: { province: '广东', city: '深圳' }, createTime: ISODate('2025-09-11T09:09:48.644Z') }, { _id: ObjectId('68c29215df0d1d729cfa3351'), name: '李四', age: 30, email: 'lisi@example.com', hobbies: [ '读书', '跑步' ], createTime: ISODate('2025-09-11T09:10:45.496Z') }, { _id: ObjectId('68c29215df0d1d729cfa3352'), name: '王五', age: 28, email: 'wangwu@example.com', hobbies: [ '旅行', '摄影' ], address: { province: '浙江', city: '杭州' }, createTime: ISODate('2025-09-11T09:10:45.496Z') } ] ``` ```sql test> db.users.findOne({ age: 28 }) { _id: ObjectId('68c29215df0d1d729cfa3352'), name: '王五', age: 28, email: 'wangwu@example.com', hobbies: [ '旅行', '摄影' ], address: { province: '浙江', city: '杭州' }, createTime: ISODate('2025-09-11T09:10:45.496Z') } test> ``` **3. 更新文档** 更新文档需指定 “查询条件” 和 “更新内容”,核心方法为 updateOne()(更新匹配的第一条)、updateMany()(更新所有匹配项)、replaceOne()(替换整个文档)。 **关键:更新操作需使用 “更新操作符”**(如 $set 改字段、$inc 增减数值),否则会替换整个文档(除 _id 外)。 | 更新需求 | 命令示例 | 解释 | | ------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | | 更新单个文档(改字段) | db.users.updateOne( { name: "张三" }, { $set: { age: 26, email: "zhangsan_new@example.com" } } ) | 1. 条件:name="张三";2. 更新:$set 设 age=26、改邮箱;只更新第一条匹配项 | | 更新多个文档(增减数值) | db.users.updateMany( { age: { $lt: 30 } }, { $inc: { age: 1 } } ) | 1. 条件:年龄 < 30;2. $inc 使 age 增加 1(所有匹配项年龄 + 1) | | 替换整个文档 | db.users.replaceOne( { name: "王五" }, { name: "王五", age: 29, email: "wangwu_new@example.com", hobbies: ["爬山"] } ) | 替换 “name = 王五” 的文档(**必须包含所有字段**,否则原字段会丢失,除 _id 外) | | 新增字段 | db.users.updateOne( { name: "李四" }, { $set: { gender: "男" } } ) | 若 gender 字段不存在,$set 会自动新增该字段 | | 删除字段 | db.users.updateOne( { name: "李四" }, { $unset: { gender: "" } } ) | $unset 用于删除字段,值可设为空字符串 | ```json test> db.users.updateMany( { age: { $lt: 30 } }, { $inc: { age: 1 } } ) { acknowledged: true, insertedId: null, matchedCount: 2, modifiedCount: 2, upsertedCount: 0 } test> ``` **返回结果**:包含 matchedCount(匹配的文档数)和 modifiedCount(实际修改的文档数) **4. 删除文档** 删除文档需指定 “查询条件”,核心方法为 deleteOne()(删除第一条匹配项)和 deleteMany()(删除所有匹配项),**谨慎操作,建议先查询确认再删除**。 | 删除需求 | 命令示例 | 解释 | | ------------------------ | ------------------------------------------- | ------------------------------------------------------------ | | 删除单个文档 | db.users.deleteOne( { name: "张三" } ) | 删除 “name = 张三” 的**第一条文档**(若有多个同名,只删第一个) | | 删除多个文档 | db.users.deleteMany( { age: { $gt: 28 } } ) | 删除 “年龄> 28” 的**所有文档**(批量删除) | | 删除所有文档(清空集合) | db.users.deleteMany({}) | 条件为空,删除集合中所有文档(集合结构保留,仅数据清空,比删除集合高效) | ```sql test> db.users.deleteMany( { age: { $gt: 28 } } ) { acknowledged: true, deletedCount: 2 } test> ``` **返回结果**:包含 deletedCount(删除的文档数) ## 操作符 MongoDB 提供了丰富的操作符(Operators),用于实现复杂的查询、更新、聚合等操作。这些操作符按功能可分为 **查询操作符**、**更新操作符**、**聚合操作符** 和 **数组操作符** 等 **查询操作符** 用于 find()、findOne() 等查询方法,定义筛选条件,格式为 { 字段: { 操作符: 值 } }。 比较操作符(Comparison):用于比较字段值,是最基础的查询条件。 | 操作符 | 含义 | 示例(查询 users 集合) | | ------ | ------------------ | ------------------------------------------------------------ | | $eq | 等于(默认可省略) | db.users.find({ age: { $eq: 25 } }) → 查询年龄等于 25 的用户 | | $ne | 不等于 | db.users.find({ age: { $ne: 25 } }) → 查询年龄不等于 25 的用户 | | $gt | 大于 | db.users.find({ age: { $gt: 25 } }) → 查询年龄大于 25 的用户 | | $gte | 大于等于 | db.users.find({ age: { $gte: 25 } }) → 查询年龄大于等于 25 的用户 | | $lt | 小于 | db.users.find({ age: { $lt: 30 } }) → 查询年龄小于 30 的用户 | | $lte | 小于等于 | db.users.find({ age: { $lte: 30 } }) → 查询年龄小于等于 30 的用户 | | $in | 在指定数组内 | db.users.find({ hobby: { $in: ["篮球", "足球"] } }) → 查询爱好是篮球或足球的用户 | | $nin | 不在指定数组内 | db.users.find({ hobby: { $nin: ["篮球", "足球"] } }) → 查询爱好不是篮球且不是足球的用户 | 逻辑操作符(Logical):用于组合多个条件,实现复杂逻辑判断。 | 操作符 | 含义 | 示例(查询 users 集合) | | ------ | -------------------------- | ------------------------------------------------------------ | | $and | 逻辑与(所有条件满足) | db.users.find({ $and: [{ age: { $gt: 25 } }, { gender: "男" }] }) → 年龄 > 25 且 性别为男 | | $or | 逻辑或(任一条件满足) | db.users.find({ $or: [{ age: { $lt: 18 } }, { age: { $gt: 60 } }] }) → 年龄 <18 或 年龄> 60 | | $not | 逻辑非(条件取反) | db.users.find({ age: { $not: { $gt: 25 } } }) → 年龄不大于 25(即 ≤25) | | $nor | 逻辑与非(所有条件不满足) | db.users.find({ $nor: [{ age: { $lt: 18 } }, { age: { $gt: 60 } }] }) → 年龄≥18 且 ≤60 | 元素操作符(Element):用于检查字段是否存在或字段类型。 | 操作符 | 含义 | 示例(查询 users 集合) | | ------- | ---------------- | ------------------------------------------------------------ | | $exists | 字段是否存在 | db.users.find({ address: { $exists: true } }) → 查询存在 address 字段的用户 | | $type | 字段类型是否匹配 | db.users.find({ age: { $type: "int" } }) → 查询 age 字段类型为整数的用户(支持 string、date 等) | 数组操作符(Array):用于查询数组类型字段的元素。 | 操作符 | 含义 | 示例(查询 users 集合) | | ---------- | ------------------------------ | ------------------------------------------------------------ | | $all | 数组包含所有指定元素 | db.users.find({ hobby: { $all: ["篮球", "游戏"] } }) → 爱好同时包含篮球和游戏的用户 | | $elemMatch | 数组中至少一个元素满足所有条件 | db.users.find({ scores: { $elemMatch: { $gt: 80, $lt: 90 } } }) → 成绩数组中存在 80~90 分的用户 | | $size | 数组长度等于指定值 | db.users.find({ hobby: { $size: 2 } }) → 爱好数组长度为 2 的用户 | 文本查询操作符(Text):用于全文检索(需先创建文本索引)。 | 操作符 | 含义 | 示例(查询 articles 集合) | | --------- | ------------------------------ | ------------------------------------------------------------ | | $text | 匹配文本内容 | db.articles.find({ $text: { $search: "mongodb 教程" } }) → 匹配包含 “mongodb” 或 “教程” 的文章 | | $language | 指定文本语言(支持多语言分词) | db.articles.find({ $text: { $search: "mongodb", $language: "en" } }) → 按英文分词检索 | 等等,还有许多操作符,就不一一列举。 官方操作手册:https://www.mongodb.com/zh-cn/docs/manual/。 常用操作符以及场景 | 操作类型 | 核心操作符 | 典型场景 | | ------------ | --------------------------- | ---------------------------------------------------- | | **基础查询** | $eq、$gt、$lt、$in、$or | 按条件筛选数据(如年龄范围、多值匹配) | | **数组查询** | $all、$elemMatch、$size | 筛选数组包含特定元素或满足条件的文档(如爱好、成绩) | | **数据更新** | $set、$inc、$push、$pull | 修改字段值、增减数值、更新数组(如用户信息修改) | | **数据统计** | $group、$sum、$avg、$lookup | 分组统计、关联查询(如按地区统计用户数、关联订单) | ## 用户与权限管理核心概念 MongoDB 作为最流行的文档型 NoSQL 数据库,其用户与权限管理基于**角色访问控制(RBAC)** 模型,核心逻辑是:通过 “用户(User)” 关联 “角色(Role)”,“角色” 聚合 “权限(Privilege)”,最终实现对数据库资源的细粒度控制。 与关系型数据库(如 MySQL、Oracle)相比,MongoDB 的权限管理更轻量但灵活,专注于文档、集合和数据库级别的操作控制,适合分布式和非结构化数据场景。 **用户(User)** MongoDB 的用户**与特定数据库绑定**(用户信息存储在所属数据库的 system.users 集合中),例如 admin 数据库中的用户可管理全局资源,而 shop 数据库中的用户仅能操作 shop 数据库。 用户通过 “用户名 + 数据库 + 密码” 唯一标识,同一用户名在不同数据库中是独立用户(如 user1@admin 和 user1@shop 是两个用户)。 管理员用户通常创建在 admin 数据库(因 admin 数据库的角色权限范围更大)。 **角色(Role)** 角色是 “权限的集合”,用于简化权限分配。MongoDB 分为**内置角色**(系统预定义)和**自定义角色**(用户创建): 角色的作用范围: - 数据库级角色:仅对所属数据库生效(如 read@shop 角色仅允许读取 shop 数据库)。 - 集群级角色:对整个 MongoDB 集群生效(如 clusterAdmin 管理集群配置)。 - 超级用户角色:如 root 拥有所有权限,等价于关系型数据库的 DBA。 **权限(Privilege)** 权限是对具体资源的操作许可,格式为 { resource: ..., actions: [...] }: 资源(resource):指定权限作用的对象,可分为: - { db: "数据库名", collection: "集合名" }(特定数据库的特定集合) - { db: "数据库名", collection: "" }(特定数据库的所有集合) - { cluster: true }(整个集群)。 **操作(actions)**:允许执行的具体操作,如 find(查询)、insert(插入)、remove(删除)、createIndex(创建索引)等。 ## 用户管理 MongoDB 默认不启用认证(即无需用户名密码即可登录),生产环境必须先**启用认证机制**,再创建用户。 **启用认证** 步骤 1:修改配置文件(mongod.conf) ```yaml # Linux/Mac 通常路径:/etc/mongod.conf 或 /usr/local/etc/mongod.conf # Windows 通常路径:C:\Program Files\MongoDB\Server\版本号\bin\mongod.cfg security: authorization: enabled # 启用认证(默认 disabled) ``` 步骤 2:重启 MongoDB 服务 ```yaml # Linux 重启 sudo systemctl restart mongod # Windows 重启(服务名通常为 MongoDB) net stop MongoDB net start MongoDB ``` **创建用户** ```yaml db.createUser({ user: "用户名", pwd: "密码", // 或用 passwordPrompt() 交互式输入 roles: [ { role: "角色名", db: "作用数据库" }, // 角色及作用范围 "角色名@数据库名" // 简写形式(如 "readWrite@shop") ], customData: { "描述": "用户备注" } // 可选:用户附加信息 }) ``` 关键说明 - 角色格式:可指定 { role: "read", db: "shop" } 或简写为 "read@shop"。 - 密码安全:生产环境需使用强密码(建议长度≥8,包含大小写、数字、特殊字符),可通过 passwordPrompt() 避免明文输入。 - 用户所属数据库:当前连接的数据库即为用户所属数据库(如连接 admin 数据库创建的用户属于 admin)。 ```javascript // 示例1:创建集群管理员(admin数据库,拥有集群管理权限) use admin // 切换到admin数据库(管理员用户通常在此创建) db.createUser({ user: "cluster_admin", pwd: passwordPrompt(), // 执行后会提示输入密码(推荐) roles: [ "clusterAdmin", // 集群管理(如分片、复制集配置) "readAnyDatabase" // 读取所有数据库 ], customData: { "desc": "集群管理员,负责维护集群配置" } }) // 示例2:创建业务数据库(shop)的读写用户 use shop // 切换到shop数据库(用户属于shop) db.createUser({ user: "shop_app", pwd: "Shop@App2024", roles: [ { role: "readWrite", db: "shop" } // 允许读写shop数据库的所有集合 ] }) // 示例3:创建只读用户(仅允许查询shop数据库的products集合) use shop db.createUser({ user: "shop_reader", pwd: "Shop@Read2024", roles: [ { role: "read", db: "shop" // 基础只读权限(所有集合) }, // 后续可通过自定义角色限制到特定集合(见下文) ] }) ``` **修改用户** 用于修改用户密码、角色、附加信息等。 ```yaml db.updateUser( "用户名", // 要修改的用户 { pwd: "新密码", // 可选:修改密码 roles: [新角色列表], // 可选:替换原有角色(注意是替换而非添加) customData: { 新附加信息 }, // 可选:更新附加信息 mechanisms: ["SCRAM-SHA-256"] // 可选:指定认证机制(默认SCRAM-SHA-1/256) } ) ``` ```javascript // 示例1:修改shop_app用户的密码 use shop // 切换到用户所属数据库 db.updateUser("shop_app", { pwd: "NewShop@App2024" }) // 示例2:更新shop_reader用户的角色(添加对logs数据库的只读权限) use shop db.updateUser("shop_reader", { roles: [ { role: "read", db: "shop" }, // 保留原有权限 { role: "read", db: "logs" } // 添加新权限 ] }) ``` **删除用户** ```yaml // 语法:db.dropUser("用户名") // 示例:删除shop数据库的shop_reader用户 use shop db.dropUser("shop_reader") // 返回true表示成功 ``` **用户认证** 创建用户后,需通过认证才能操作数据库,常用两种方式: 方式一:连接时指定认证信息 ```sql # 命令行连接(用户名:shop_app,数据库:shop) mongo -u shop_app -p Shop@App2024 --authenticationDatabase shop # 连接远程数据库(IP:192.168.1.100,端口:27017) mongo "mongodb://192.168.1.100:27017/shop" -u shop_app -p Shop@App2024 ``` 方式二:连接后认证 ```sql // 先连接数据库,再执行认证 mongo # 连接本地默认实例 use shop # 切换到用户所属数据库 db.auth("shop_app", "Shop@App2024") # 返回1表示认证成功,0表示失败 ``` ## 角色与权限管理 MongoDB 提供丰富的内置角色,覆盖大多数场景;特殊需求可创建自定义角色。 **内置角色** 内置角色按 “作用范围” 分为数据库级、集群级和超级用户级,以下是最常用的角色: | 角色类型 | 角色名 | 权限说明 | | -------------- | -------------------- | ------------------------------------------------------------ | | **数据库级** | read | 允许读取数据库的所有集合(操作:find、count、distinct 等) | | | readWrite | 包含 read 权限 + 写入操作(insert、update、remove 等) | | | dbAdmin | 数据库管理权限(创建索引、集合、查看统计信息等,无读写数据权限) | | | dbOwner | 数据库所有者(readWrite + dbAdmin + userAdmin 权限) | | | userAdmin | 管理当前数据库的用户(创建 / 修改 / 删除用户和角色) | | **集群级** | clusterAdmin | 集群最高管理权限(配置分片、复制集、监控集群等) | | | clusterMonitor | 集群监控权限(查看集群状态、日志等,无修改权限) | | **超级用户级** | root | 所有数据库和集群的权限(等价于 dbOwner@所有数据库 + clusterAdmin) | | | readAnyDatabase | 读取所有数据库的权限(除 local 和 config 数据库) | | | userAdminAnyDatabase | 管理所有数据库的用户(创建 / 修改所有数据库的用户) | **自定义角色** 当内置角色无法满足需求(如限制仅操作特定集合),可创建自定义角色。 ```javascript db.createRole({ role: "角色名", privileges: [ // 权限列表(资源+操作) { resource: { db: "数据库名", collection: "集合名" }, // 作用资源 actions: ["操作1", "操作2"] // 允许的操作 } ], roles: [ // 继承的其他角色(可选) { role: "继承角色名", db: "数据库名" } ] }) ``` 常用操作(actions)说明: | 操作类别 | 常用操作 | | -------- | ------------------------------------------------------------ | | 查询 | find(查询文档)、count(计数)、distinct(去重查询) | | 写入 | insert(插入)、update(更新)、remove(删除) | | 管理 | createIndex(创建索引)、dropIndex(删除索引)、createCollection(创建集合) | ```javascript // 需求:创建角色 shop_products_reader,仅允许查询 shop 数据库的 products 集合 use shop // 在shop数据库创建角色(角色作用范围为当前数据库) db.createRole({ role: "shop_products_reader", privileges: [ { resource: { db: "shop", collection: "products" }, // 仅作用于products集合 actions: ["find", "count", "distinct"] // 仅允许查询相关操作 } ], roles: [] // 不继承其他角色 }) // 将角色授予用户 shop_reader db.grantRolesToUser("shop_reader", ["shop_products_reader"]) ``` **授予角色** 向用户添加角色(**追加**而非替换原有角色): ```javascript // 语法:db.grantRolesToUser("用户名", [角色列表]) // 示例:给 shop_app 用户添加 dbAdmin@shop 角色 use shop db.grantRolesToUser("shop_app", [{ role: "dbAdmin", db: "shop" }]) ``` **回收角色** 从用户移除角色: ```javascript // 语法:db.revokeRolesFromUser("用户名", [角色列表]) // 示例:从 shop_app 用户移除 dbAdmin@shop 角色 use shop db.revokeRolesFromUser("shop_app", [{ role: "dbAdmin", db: "shop" }]) ``` **删除角色** ```javascript // 语法:db.dropRole("角色名") // 示例:删除 shop_products_reader 角色 use shop db.dropRole("shop_products_reader") ``` ## 权限查询与审计 通过系统命令和集合查询用户、角色和权限信息。 **查询用户信息** ```javascript // 1. 查看当前数据库的所有用户 use shop db.getUsers() // 返回用户列表(含角色、创建时间等) // 2. 查看指定用户的详细信息 db.getUser("shop_app") // 返回shop_app用户的角色、权限等 // 3. 查看所有数据库的用户(需管理员权限,在admin数据库执行) use admin db.system.users.find().pretty() // 所有用户存储在admin.system.users集合 ``` **查看角色信息** ```javascript // 1. 查看当前数据库的所有角色 use shop db.getRoles() // 返回角色列表 // 2. 查看指定角色的权限详情 db.getRole("shop_products_reader", { showPrivileges: true }) // 显示角色包含的权限 // 3. 查看内置角色的权限(如read角色) db.getRole("read", { showPrivileges: true }) ``` **查看用户拥有的权限** ```javascript // 1. 查看当前数据库的所有角色 use shop db.getRoles() // 返回角色列表 // 2. 查看指定角色的权限详情 db.getRole("shop_products_reader", { showPrivileges: true }) // 显示角色包含的权限 // 3. 查看内置角色的权限(如read角色) db.getRole("read", { showPrivileges: true }) ```
毛林
2025年9月12日 20:57
转发文档
收藏文档
上一篇
下一篇
手机扫码
复制链接
手机扫一扫转发分享
复制链接
Markdown文件
PDF文档(打印)
分享
链接
类型
密码
更新密码