如何在Google Firebase Firestore规则中验证验证码与用户认证?
问题
我在Firebase部署的网站上做了一个收集用户邮箱的简易表单,为防止机器人提交,已启用带ReCaptchaV3的App Check。网站没有注册功能,采用匿名认证为每个用户自动分配ID,要求用户仅能提交一次。
现在需要在Firestore规则中同时检查用户已完成匿名认证和App Check验证码验证通过,当前遇到权限错误。
提交数据的函数代码
export const writeUserData = async (email) => { const db = getFirestore(); const uid = auth.currentUser?.uid const docRef = await addDoc(collection(db, `newsletter/${uid}/entries`), { email: email }); console.log(docRef); }
当前Firestore规则集
rules_version = '2'; service cloud.firestore { match /databases/{database}/documents { allow read: if false; match /newsletter/{userId}/entries { allow write: if request.auth != null; } } }
错误提示
未捕获(在 promise 中)FirebaseError:权限缺失或不足。
解决方案
要同时满足认证检查、App Check验证和单次提交限制,需要修改Firestore规则,具体如下:
- 验证App Check通过:启用App Check后,合法请求会携带App验证信息,规则中通过
request.app != null判断验证是否通过。 - 验证用户身份一致性:确保请求路径中的
userId和当前认证用户的uid一致,防止恶意伪造提交路径。 - 限制单次提交:检查该用户的
entries集合下无已有文档,保证只能提交一次。
修改后的Firestore规则
rules_version = '2'; service cloud.firestore { match /databases/{database}/documents { allow read: if false; match /newsletter/{userId}/entries { allow create: if // 验证用户已完成匿名认证 request.auth != null && // 确保路径userId与当前用户uid一致 request.auth.uid == userId && // 验证App Check验证码通过 request.app != null && // 确保用户从未提交过(entries集合为空) get(/databases/$(database)/documents/newsletter/$(userId)/entries).size() == 0; } } }
额外优化建议
提交函数中建议先判断用户是否完成匿名认证,避免因未认证导致的空值错误:
export const writeUserData = async (email) => { const db = getFirestore(); let user = auth.currentUser; // 若未认证则触发匿名登录 if (!user) { await signInAnonymously(auth); user = auth.currentUser; } if (!user?.uid) return; const docRef = await addDoc(collection(db, `newsletter/${user.uid}/entries`), { email: email }); console.log(docRef); }
内容的提问来源于stack exchange,提问作者Enigma Logoy
相关产品推荐
相关产品推荐

