Firebase+NextAuth+FirestoreAdapter如何配置所有者专属读写安全规则?
Firebase + NextAuth + Firestore 安全规则配置问题
问题背景
我基于 Firebase + NextJS,通过 NextAuth 和 FirestoreAdapter 实现认证功能。调试阶段用了全权限开放的安全规则,所有功能都正常运行:
service cloud.firestore { match /databases/{database}/documents { match /{document=**} { allow read, write: if true } } }
但显然这种规则在生产环境会有极大安全隐患,我需要设置更严格的规则——仅允许文档所有者进行读写操作。尝试过一个解决方案但没能成功:
match /store/{userId}/{document=**} { allow read, write: if request.auth.token.id == userId && exists(/databases/$(database)/documents/tokens/$(request.auth.uid)/sessions/$(request.auth.token.sessionToken)); }
核心问题
问题根源在于 NextAuth 与 FirestoreAdapter、Firestore 数据库的交互逻辑:我创建新文档时,文档会被存在users → session.user.id → drafts → 文档路径下,但 Firebase 的用户 UID 和session.user.id并不一致,这直接导致之前的安全规则失效。
现在需要找到正确的安全规则配置方式,让只有session.user.id与文档的userId字段匹配的用户,才能对数据库进行读写操作。

相关代码
创建新草稿的代码
const createNewDraft = async () => { const doc = await addDoc( collection(db, "users", session?.user?.id!, "drafts"), { userId: session?.user?.id!, createdAt: serverTimestamp(), } ); };
[...nextAuth].ts 代码
import { FirestoreAdapter } from "@next-auth/firebase-adapter"; import { GoogleAuthProvider, signInWithCredential } from "firebase/auth"; import { cert } from "firebase-admin/app"; import NextAuth from "next-auth"; import GoogleProvider from "next-auth/providers/google"; import "firebase/firestore"; import { fbAuth } from "../../../../firebase"; const sa = JSON.parse(process.env.NEXT_PUBLIC_FIREBASE_SERVICE_KEY); export const authOptions = { providers: [ GoogleProvider({ clientId: process.env.NEXT_PUBLIC_GOOGLE_CLIENT_ID!, clientSecret: process.env.NEXT_PUBLIC_GOOGLE_CLIENT_SECRET!, }), ], callbacks: { async signIn({ user, account, profile, email, credentials }) { try { const googleCredential = GoogleAuthProvider.credential( account?.id_token ); const userCredential = await signInWithCredential( fbAuth, googleCredential ).catch((e) => { console.log(e); return false; }); return !!userCredential; } catch (e) { console.log(e); return false; } }, session: async ({ session, token }) => { if (session?.user) { session.user.id = token.sub; } return session; }, }, session: { strategy: "jwt", }, adapter: FirestoreAdapter({ credential: cert({ projectId: sa.project_id, clientEmail: sa.client_email, privateKey: sa.private_key, }), }), }; export default NextAuth(authOptions);
内容的提问来源于stack exchange,提问作者Tyler Kim
相关产品推荐
相关产品推荐

