Firebase Realtime Database规则安全配置、登录权限及用户数据隔离问题咨询
Firebase Realtime Database 安全规则配置解决方案
问题根源说明
- 权限被拒绝报错:你在注册、登录流程中,还未完成OTP认证拿到Firebase Auth身份凭证时,就发起了对Users节点的手机号查询请求,此时
auth对象为空,匹配auth.uid != null规则时会直接被拒绝。 - 无法实现用户数据隔离:你将读权限配置在
/Users父节点,只要权限校验通过,用户就可以读取该节点下所有子数据,父节点授予的权限无法在子节点收回,因此无法做到单用户数据隔离。
方案1:调整安全规则+优化业务流程(更安全,推荐)
第一步:更新安全规则
{ "rules": { ".write": "root.child('Admins').child(auth.uid).exists()", "Admins": { ".read": true, ".write": false }, "Users": { // 父节点不开放全局读写权限,仅在单用户子节点授权 "$userUid": { // 仅用户本人可以读写自己的用户数据 ".read": "auth != null && auth.uid == $userUid", ".write": "auth != null && auth.uid == $userUid", // 校验写入数据格式合法性,可根据业务需求调整 ".validate": "newData.hasChild('phoneNumber') && newData.child('uid').val() == $userUid" } }, "PrivateWork": { ".read": "auth.uid != null", ".write": false }, "Likes": { ".read": "auth.uid != null", ".write": "auth.uid != null" }, "Work": { ".read": "auth.uid != null", ".write": false }, "videos": { ".read": "auth.uid != null", ".write": false } } }
第二步:调整业务流程
原有流程:输入手机号 → 未认证状态查询Users节点判断账号是否存在 → 走对应OTP认证流程
调整后流程:
- 不管是注册还是登录,用户输入手机号后直接发起OTP认证,先完成Firebase Auth身份校验,拿到当前用户的
auth.uid - 认证完成后,用拿到的uid查询
/Users/{auth.uid}节点是否存在- 节点存在:直接进入登录后页面
- 节点不存在:引导用户补全注册信息,写入到
/Users/{auth.uid}节点完成注册
该方案完全不需要在未认证状态下查询Users节点,既解决了权限报错问题,也杜绝了手机号被恶意枚举的安全风险。
方案2:保留原有流程,调整规则适配(临时过渡用)
如果你暂时不想修改现有业务流程,可以通过增加查询限制规则适配原有逻辑,弊端是存在手机号被枚举的风险:
{ "rules": { ".write": "root.child('Admins').child(auth.uid).exists()", "Admins": { ".read": true, ".write": false }, "Users": { ".read": false, // 仅允许通过phoneNumber字段精准查询,不允许全量遍历 ".query": { "orderByChild": "phoneNumber", "queryEqual": true }, "$userUid": { ".read": "auth != null && auth.uid == $userUid", ".write": "auth != null && auth.uid == $userUid", ".validate": "newData.hasChild('phoneNumber') && newData.child('uid').val() == $userUid" } }, "PrivateWork": { ".read": "auth.uid != null", ".write": false }, "Likes": { ".read": "auth.uid != null", ".write": "auth.uid != null" }, "Work": { ".read": "auth.uid != null", ".write": false }, "videos": { ".read": "auth.uid != null", ".write": false } } }
内容的提问来源于stack exchange,提问作者MiniDev99
相关产品推荐
相关产品推荐

