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

Firestore安全规则:基于数组字段管控父文档与嵌套集合权限

解决方案

核心思路

利用Firestore规则的get()方法获取父级accounts文档验证权限,同时强制查询携带accountId in条件,确保规则仅验证用户有权访问的账户ID,避免无差别遍历父文档导致的性能或规则拒绝问题。

安全规则实现

// 判断是否为拥有全权限的管理员
function isAdmin() {
  // 根据你的实际admin配置调整,示例为检查邮箱是否在admins集合中
  return exists(/databases/$(database)/documents/admins/$(request.auth.token.email));
}

// 验证用户是否有权访问指定账户
function canAccessAccount(accountId) {
  if (isAdmin()) return true;
  const accountRef = /databases/$(database)/documents/accounts/$(accountId);
  return exists(accountRef) && get(accountRef).data.users.hasAny([request.auth.token.email]);
}

// 针对projects集合组的读取规则
match /{document=**}/projects/{project} {
  allow read: if request.auth != null && (
    isAdmin() ||
    (
      // 强制查询必须包含accountId的in过滤条件
      'accountId' in request.query && request.query.accountId.op == 'in' &&
      // 验证查询列表中的每个accountId用户都有权访问
      request.query.accountId.value.every(accountId => canAccessAccount(accountId)) &&
      // 最终校验当前项目对应的账户确实是用户有权访问的
      canAccessAccount(resource.data.accountId)
    )
  );
}

关键说明

  1. 权限复用:通过isAdmin和canAccessAccount函数复用现有权限逻辑,避免规则冗余。
  2. 查询强制校验:要求查询必须携带accountId in条件,确保规则仅处理用户预先筛选的账户ID,大幅降低权限验证的开销。
  3. 双重验证:既校验查询列表的合法性,又单独校验当前项目的账户权限,防止恶意构造查询绕过规则。

前端代码注意事项

你当前的查询代码无需修改:

this.firestore.collectionGroup('projects', (ref) => ref.where('accountId','in',accountIds)).get()

只需确保accountIds是前端从accounts集合中预先查询到的、包含当前用户邮箱的文档ID数组,这样就能和规则形成完整的权限闭环。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 23:24:37