如何在单应用中使用多Firestore实例并启用request.auth非空访问规则?
问题:如何让次级Firebase项目的Firestore仅允许主项目的登录用户访问?
我基于Firebase Web SDK构建应用,主项目配置了Auth和Firestore,次级项目仅配置Firestore。当前已通过初始化独立App实例的方式连接次级Firestore,但只有当次级Firestore规则设为allow read: if true;时才能正常访问。若改为allow read: if request.auth != null;,会触发Error: Missing or insufficient permissions,推测是因为用户仅在主项目登录,次级项目的request.auth为空。
核心原因
每个Firebase App实例的身份验证状态是独立的,主项目的登录会话不会自动同步到次级项目,因此次级Firestore的安全规则无法识别主项目的登录用户,request.auth为空导致权限被拒。
解决方案
方案1:跨项目同步用户身份(客户端实现)
将主项目的用户凭证传递给次级项目,让次级项目的Auth实例识别该用户,这样次级Firestore的request.auth就能获取到用户信息。
步骤:
- 获取主项目登录用户的ID Token
- 使用该Token作为自定义凭证,在次级项目的Auth实例中完成登录
代码示例(TypeScript):
import { getAuth, getIdToken } from "firebase/auth"; import { getAuth as getSecondAuth, signInWithCustomCredential } from "firebase/auth"; import { secondApp } from "./path-to-your-second-app-config"; // 获取主项目Auth实例及当前登录用户 const mainAuth = getAuth(); const currentUser = mainAuth.currentUser; if (currentUser) { try { // 获取主项目用户的ID Token const idToken = await getIdToken(currentUser); // 初始化次级项目的Auth实例 const secondAuth = getSecondAuth(secondApp); // 使用自定义凭证在次级项目中登录 await signInWithCustomCredential(secondAuth, idToken); // 现在访问次级Firestore时,request.auth会包含用户信息 } catch (error) { console.error("跨项目身份验证失败:", error); } }
此时次级Firestore的规则可保持:
rules_version = '2'; service cloud.firestore { match /databases/{database}/documents { match /{document=**} { allow read: if request.auth != null; allow write: if false; } } }
方案2:通过安全规则验证主项目用户身份
无需在客户端同步登录状态,直接在次级Firestore的安全规则中验证用户Token是否由主项目签发。
规则示例:
rules_version = '2'; service cloud.firestore { match /databases/{database}/documents { match /{document=**} { // 替换为你的主项目ID,验证Token的签发来源 allow read: if request.auth != null && request.auth.token.iss == "https://securetoken.google.com/your-main-project-id"; allow write: if false; } } }
这种方式需要确保客户端请求次级Firestore时,携带的是主项目的用户Token,可通过方案1的方式让次级Auth实例自动在请求中携带凭证。
方案3:后端代理(适合有服务端的场景)
如果你的应用有后端服务,可以使用Firebase Admin SDK来处理次级Firestore的访问:
- 客户端将主项目的用户ID Token发送到后端
- 后端用Admin SDK验证Token的有效性(确认用户来自主项目)
- 验证通过后,后端使用Admin SDK访问次级Firestore并返回数据给客户端
- 次级Firestore的规则可设置为仅允许Admin SDK访问:
rules_version = '2'; service cloud.firestore { match /databases/{database}/documents { match /{document=**} { allow read: if request.auth.token.admin == true; allow write: if false; } } }
内容的提问来源于stack exchange,提问作者TinyTiger
相关产品推荐
相关产品推荐

