如何通过Firestore安全规则校验自定义字段实现文档访问权限控制
这个需求完全可以实现,通过Firestore安全规则的查询条件校验能力就能完成,不需要依赖用户登录体系,适配非用户维度token的场景,具体配置如下:
一、前端查询代码要求
前端JS侧发起查询时,必须同时携带token和name两个等值过滤条件,示例代码:
import { getFirestore, collection, query, where, getDocs } from "firebase/firestore"; const db = getFirestore(); // 从URL中获取请求参数 const urlParams = new URLSearchParams(window.location.search); const inputToken = urlParams.get('token'); const inputName = urlParams.get('name'); // 构造查询条件,必须同时包含两个字段的等值匹配 const tokenQuery = query( collection(db, "funTokens"), // 如果token是数字类型就保留Number转换,是字符串就去掉Number where("token", "==", Number(inputToken)), where("name", "==", inputName) ); // 执行查询 const querySnapshot = await getDocs(tokenQuery); querySnapshot.forEach((doc) => { // 只有匹配的文档会被返回,安全规则已经提前过滤了不匹配的请求 console.log(doc.id, " => ", doc.data()); });
二、Firestore安全规则配置
直接在Firebase控制台的安全规则页写入如下规则即可:
rules_version = '2'; service cloud.firestore { match /databases/{database}/documents { // 匹配funTokens集合下的所有文档 match /funTokens/{docId} { allow read: if ( // 1. 校验请求必须同时携带token、name两个等值查询条件 request.query.where.keys().hasAll(['token', 'name']) && // 2. 校验查询传入的token和文档存储的token完全匹配 request.query.where.token == resource.data.token && // 3. 校验查询传入的name和文档存储的name完全匹配 request.query.where.name == resource.data.name && // 4. 可选校验:保证集合内文档ID和token值一致,符合你的数据结构设计 // 如果token是字符串类型就去掉string转换 docId == string(resource.data.token) ); // 禁止所有写操作,有写入需求可以单独配置规则 allow write: if false; } } }
三、额外注意事项
- 首次使用该查询前需要在Firestore控制台创建
token和name的联合索引,控制台会在首次查询报错时给出自动创建入口,点击即可完成创建,查询性能不受集合量级影响,哪怕集合内有千万级token也可以正常响应。 - 规则不依赖任何用户登录状态,完全通过查询参数校验完成权限控制,符合你提到的token不属于用户维度实体的要求。
内容的提问来源于stack exchange,提问作者alon
相关产品推荐
相关产品推荐

