已完成Firebase手机号认证,操作Firestore时安全规则识别request.auth为null
问题核心成因
从你提供的请求日志解码后可以直接定位根因:请求头里携带的Bearer令牌是签名算法为none的未签名无效JWT,不具备Firebase认证信任的合法性,因此Firestore安全规则引擎校验令牌不通过,直接将request.auth置为null。
关键佐证
你日志里携带的Authorization值解码后,JWT头内容为:{"alg":"none","typ":"JWT"}
- 正规由Firebase Auth服务端签发的合法ID Token,必须是RS256算法签名的格式,Header不会出现
alg: none - 引擎不会校验任何签名算法为none的令牌内容,哪怕令牌payload里已经正确写入了你的uid
pbc5l8cca7ELtwM0Kxctn9xLeT2i,也会被直接判定为无效认证,丢弃auth上下文 - 这种带Bearer头但auth为null的现象,和未认证状态下完全没有令牌的场景表现有明显区别:未认证时SDK不会主动携带Authorization头
常见触发场景
- 手机号登录流程未走完完整校验:没有完成reCAPTCHA人机验证、没有等待
signInWithPhoneNumber的Promise成功resolve,就触发了Firestore写入操作。此时SDK可能会自动携带本地生成的未签名临时凭证当请求头,这类临时凭证本身就是alg:none格式,不具备认证效力。 - 提前触发数据库操作:没有等
getIdToken()的异步Promise返回拿到正式ID Token,就直接发起写入,SDK自动塞入请求头的是本地缓存的未完成签名流程的临时凭证。 - 本地认证缓存异常:旧的测试残留无效令牌没有被SDK清理,请求时误将残量缓存带上。
对应修复步骤
- 校验认证状态触发逻辑:必须在
onAuthStateChanged监听到用户登录成功的回调触发后,再发起Firestore操作,禁止在认证流程未完成时提前调用数据库接口。 - 强制刷新合法令牌:每次写操作前,显式调用
await user.getIdToken(true)获取服务端最新签发的RS256签名ID Token,再执行写入。 - 检查手机号登录的reCAPTCHA配置:确认没有跳过人机验证的逻辑,模拟手机号登录生成的临时凭证不具备正式认证效力。
- 清理本地无效缓存:清空localStorage中Firebase SDK存储的旧认证数据,重新走完整的手机号验证码校验流程后再测试写入。
你当前编写的安全规则逻辑本身不存在语法或权限匹配问题,等合法的签名ID Token被正确携带到请求中,规则引擎就能正常解析到
request.auth.uid,匹配文档ID对应的所有权校验逻辑。
内容的提问来源于stack exchange,提问作者ehed
相关产品推荐
相关产品推荐

