如何解决Safari中NextJS+Firebase Auth谷歌登录遇内容拦截器错误问题
问题根因
该报错由Safari的*智能跟踪预防(ITP)*机制、第三方内容拦截插件导致,这类规则会将apis.google.com域下的资源识别为跨站跟踪资源,默认拦截加载,和你使用的Firebase 8.x版本默认OAuth认证的远程资源拉取逻辑直接相关。
可行解决方案
方案1:本地托管谷歌OAuth依赖脚本
Firebase默认会自动从谷歌远程服务器拉取api.js,你可以将该脚本下载到项目本地静态资源目录托管,绕过跨域资源拦截规则:
- 手动下载
https://apis.google.com/js/api.js文件,存放在Next项目的public/static目录下 - 初始化Firebase时添加配置,指定使用本地托管的脚本地址:
import firebase from 'firebase/app' import 'firebase/auth' const firebaseConfig = { // 此处填写你的原有Firebase项目配置 } if (!firebase.apps.length) { firebase.initializeApp(firebaseConfig) // 配置优先加载本地托管的谷歌认证脚本 window.__google_auth_js_url = '/static/api.js' firebase.auth().useDeviceLanguage() firebase.auth().setPersistence(firebase.auth.Auth.Persistence.LOCAL) }
- 后续调用
signInWithPopup/signInWithRedirect方法时,会直接加载本地脚本,不会再触发跨域资源拦截。
方案2:改用谷歌身份服务直连+Firebase凭证校验
如果本地托管方案不适用,可以放弃Firebase封装的谷歌登录方法,直接通过谷歌身份服务完成认证,再将返回的凭证交给Firebase完成登录校验,整个流程在第一方上下文触发,不会被识别为跟踪资源:
// 谷歌登录按钮点击触发逻辑 const handleGoogleSignIn = async () => { // 初始化谷歌身份客户端 window.google.accounts.id.initialize({ client_id: '你的谷歌云OAuth客户端ID', callback: async (res) => { // 转换谷歌返回的凭证为Firebase可识别的格式 const credential = firebase.auth.GoogleAuthProvider.credential(res.credential) // 完成Firebase登录 await firebase.auth().signInWithCredential(credential) } }) window.google.accounts.id.prompt() }
方案3:添加拦截场景兼容引导
部分用户手动安装的第三方内容拦截插件规则非常严格,前两种方案仍然可能被拦截,可以在用户点击谷歌登录按钮时添加资源加载检测,检测到加载失败时弹出提示,引导用户临时关闭当前站点的内容拦截规则后再继续操作。
额外注意
- 无需为解决该问题升级Firebase到9.x及以上版本,高版本Firebase的默认OAuth实现逻辑和8.x一致,同样会触发相同的拦截规则
- 所有方案都需要提前在谷歌云控制台的OAuth同意屏幕配置正确的站点域名、授权重定向地址,避免后续出现跨域校验失败问题
内容的提问来源于stack exchange,提问作者Thierry
相关产品推荐
相关产品推荐

