解决Firebase Auth注入远程脚本致Manifest V3 Chrome扩展审核被拒问题
阻止Firebase Auth注入远程脚本的方法
方法1:初始化Auth时禁用不必要的远程依赖
针对邮箱链接认证场景,可通过初始化配置禁用ReCAPTCHA和GAPI相关功能,避免SDK加载远程脚本:
import { initializeApp } from 'firebase/app'; import { getAuth } from 'firebase/auth/web-extension'; const firebaseConfig = { // 你的Firebase配置参数 }; const app = initializeApp(firebaseConfig); const auth = getAuth(app); // 禁用应用验证(邮箱链接认证无需ReCAPTCHA) auth.settings.appVerificationDisabledForTesting = true; // 清空ReCAPTCHA站点密钥,阻止SDK加载相关脚本 auth.settings.recaptchaSiteKey = null;
方法2:用Vite插件替换远程脚本地址
如果SDK仍硬编码远程脚本地址,可通过Vite的自定义插件替换这些字符串为无效值,阻止其加载:
在vite.config.js中添加:
export default { plugins: [ { name: 'strip-firebase-remote-scripts', transform(code) { return code .replace(/https:\/\/apis\.google\.com\/js\/api\.js/g, '') .replace(/https:\/\/www\.google\.com\/recaptcha\/api\.js/g, '') .replace(/https:\/\/www\.google\.com\/recaptcha\/enterprise\.js\?render=/g, ''); } } ] };
方法3:开启Vite Tree Shaking剔除冗余代码
确保Vite开启深度Tree Shaking,自动移除未使用的SDK代码分支:
// vite.config.js export default { build: { rollupOptions: { treeshake: 'smallest' } } };
符合Manifest V3规范的邮箱链接登录替代实现方案
方案1:基于Firebase REST API实现完全自定义认证
绕过Firebase JS SDK,直接调用Auth REST接口,无任何远程脚本依赖:
1. 发送登录链接
在Popup或Service Worker中调用接口:
async function sendSignInEmailLink(email) { const API_KEY = '你的Firebase API Key'; const resp = await fetch(`https://identitytoolkit.googleapis.com/v1/accounts:sendOobCode?key=${API_KEY}`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ requestType: 'SIGNIN_EMAIL_LINK', email: email, continueUrl: chrome.runtime.getURL('popup.html') }) }); const data = await resp.json(); if (data.error) throw new Error(data.error.message); return data; }
2. 验证链接并完成登录
在回调页面(如popup.html)中处理:
async function verifySignInLink(email, link) { const API_KEY = '你的Firebase API Key'; const oobCode = new URL(link).searchParams.get('oobCode'); const resp = await fetch(`https://identitytoolkit.googleapis.com/v1/accounts:signInWithEmailLink?key=${API_KEY}`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ email, oobCode }) }); const data = await resp.json(); if (data.error) throw new Error(data.error.message); // 将Token存储到Chrome本地存储 await chrome.storage.local.set({ idToken: data.idToken, refreshToken: data.refreshToken, expiresAt: Date.now() + parseInt(data.expiresIn) * 1000 }); return data; }
3. 自动刷新Token
实现Token过期自动刷新逻辑:
async function refreshAuthToken() { const API_KEY = '你的Firebase API Key'; const { refreshToken } = await chrome.storage.local.get('refreshToken'); const resp = await fetch(`https://securetoken.googleapis.com/v1/token?key=${API_KEY}`, { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, body: `grant_type=refresh_token&refresh_token=${refreshToken}` }); const data = await resp.json(); if (data.error) throw new Error(data.error.message); await chrome.storage.local.set({ idToken: data.id_token, refreshToken: data.refresh_token, expiresAt: Date.now() + parseInt(data.expires_in) * 1000 }); return data; }
方案2:结合Chrome Identity API实现认证
利用Chrome原生identity API获取用户身份,再关联Firebase Auth,无远程脚本依赖:
- 在
manifest.json中声明权限和OAuth配置:
{ "permissions": ["identity"], "oauth2": { "client_id": "你的Chrome OAuth客户端ID", "scopes": ["email", "profile"] } }
- 实现登录逻辑:
import { getAuth, signInWithCredential, OAuthCredential } from 'firebase/auth/web-extension'; async function signInWithChrome() { const auth = getAuth(); const token = await chrome.identity.getAuthToken({ interactive: true }); const credential = OAuthCredential.fromOAuth2AccessToken(token); const userCredential = await signInWithCredential(auth, credential); return userCredential.user; }
内容的提问来源于stack exchange,提问作者dino
相关产品推荐
相关产品推荐

