You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Chrome扩展Manifest V3中Firebase signInWithCredential认证报错求助

解决Chrome扩展Manifest V3中Firebase认证的auth/invalid-credential错误

问题原因

你遇到的id token is not issued by Google错误,核心是混淆了两种令牌:Firebase的getIdToken()返回的是Firebase自定义ID令牌,而非Google OAuth原生的id_token。而GoogleAuthProvider.credential(idToken)方法仅接受Google OAuth流程直接生成的令牌,因此会判定凭证无效。

解决方案

结合你需要支持Google OAuth和邮箱/密码用户的需求,以下两种方案可解决问题,其中方案1为通用所有用户类型的最优解:


方案1:使用Firebase自定义令牌(Custom Token)实现跨端认证

自定义令牌由Firebase Admin SDK生成,支持所有用户类型(Google OAuth、邮箱密码、匿名等),是最通用的跨端认证方案。

步骤:
  1. 后端生成自定义令牌
    必须在Web应用后端(前端无法安全持有Admin SDK私钥)生成自定义令牌:

    // 后端Node.js示例
    const admin = require('firebase-admin');
    
    // 初始化Admin SDK(需配置服务账号密钥)
    admin.initializeApp({
      credential: admin.credential.cert(serviceAccount)
    });
    
    // 传入用户UID生成自定义令牌
    admin.auth().createCustomToken(userUid)
      .then((customToken) => {
        // 将customToken返回给Web应用前端
        res.json({ customToken });
      })
      .catch((error) => {
        console.error('生成自定义令牌失败:', error);
        res.status(500).send('生成令牌出错');
      });
    
  2. Web应用传递令牌到扩展
    Web应用获取后端返回的自定义令牌后,通过chrome.runtime.sendMessage发送给扩展:

    // Web应用前端代码
    fetch('/api/generate-custom-token', { 
      method: 'POST', 
      body: JSON.stringify({ uid: auth.currentUser.uid }) 
    })
      .then(res => res.json())
      .then(data => {
        // 发送令牌到扩展(替换为你的扩展ID)
        chrome.runtime.sendMessage('YOUR_EXTENSION_ID', { 
          type: 'CUSTOM_TOKEN', 
          token: data.customToken 
        });
      });
    
  3. 扩展后台脚本完成认证
    扩展的Service Worker中使用signInWithCustomToken登录:

    // 扩展后台脚本(Service Worker)
    import { getAuth, signInWithCustomToken } from "firebase/auth";
    
    const auth = getAuth();
    
    // 监听Web应用的消息
    chrome.runtime.onMessageExternal.addListener((message, sender, sendResponse) => {
      if (message.type === 'CUSTOM_TOKEN') {
        signInWithCustomToken(auth, message.token)
          .then(userCredential => {
            console.log('认证成功:', userCredential.user);
            sendResponse({ success: true });
          })
          .catch(error => {
            console.error('认证失败:', error);
            sendResponse({ success: false, error: error.code });
          });
        return true; // 保持消息通道等待异步响应
      }
    });
    

方案2:针对Google OAuth用户传递原生Google id_token

如果仅需处理Google OAuth用户,可以直接传递Google原生的id_token:

步骤:
  1. Web应用获取Google原生id_token
    在Google OAuth登录流程中,从userCredential提取原生令牌:

    // Web应用Google登录代码
    import { getAuth, signInWithPopup, GoogleAuthProvider } from "firebase/auth";
    
    const auth = getAuth();
    signInWithPopup(auth, new GoogleAuthProvider())
      .then(result => {
        // 获取Google原生id_token
        const credential = GoogleAuthProvider.credentialFromResult(result);
        const googleIdToken = credential.idToken;
        // 发送到扩展
        chrome.runtime.sendMessage('YOUR_EXTENSION_ID', { 
          type: 'GOOGLE_ID_TOKEN', 
          token: googleIdToken 
        });
      })
      .catch(error => {
        console.error('登录失败:', error);
      });
    
  2. 扩展后台脚本完成认证
    扩展中使用Google原生令牌创建凭证并登录:

    // 扩展后台脚本
    import { getAuth, signInWithCredential, GoogleAuthProvider } from "firebase/auth";
    
    const auth = getAuth();
    
    chrome.runtime.onMessageExternal.addListener((message, sender, sendResponse) => {
      if (message.type === 'GOOGLE_ID_TOKEN') {
        const credential = GoogleAuthProvider.credential(message.token);
        signInWithCredential(auth, credential)
          .then(userCredential => {
            console.log('Google用户认证成功:', userCredential.user);
            sendResponse({ success: true });
          })
          .catch(error => {
            console.error('认证失败:', error);
            sendResponse({ success: false, error: error.code });
          });
        return true;
      }
    });
    

关键配置检查

  1. 确保Web应用和扩展使用完全相同的Firebase配置(apiKey、authDomain等);
  2. 在扩展的manifest.json中配置externally_connectable,允许你的Web应用域名发送消息:
    "externally_connectable": {
      "matches": ["https://your-web-app-domain.com/*"]
    }
    

内容的提问来源于stack exchange,提问作者Francesco

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 09:55:21