使用Firebase Admin SDK生成自定义令牌后验证失败求助
问题分析与解决方案
核心错误原因
你遇到的verifyIdToken() expects an ID token, but was given a custom token错误,本质是令牌类型不匹配:
createCustomToken()生成的是自定义令牌(Custom Token),用途是让客户端(比如第三方服务)通过Firebase Auth登录,交换得到官方的ID令牌/刷新令牌。verifyIdToken()方法仅用于验证ID令牌(ID Token)——这是Firebase Auth颁发的短时效用户身份令牌,无法直接验证自定义令牌。
两种可行解决方案
方案1:按Firebase标准流程交换令牌(推荐)
这是Firebase Auth设计的标准身份验证流程,步骤如下:
- 你的后端用
createCustomToken()生成自定义令牌,返回给第三方服务。 - 第三方服务拿到自定义令牌后,调用Firebase Auth客户端SDK的
signInWithCustomToken()方法,完成登录并获取ID令牌:// 第三方服务端/客户端示例代码(Node.js) const { initializeApp } = require("firebase/app"); const { getAuth, signInWithCustomToken } = require("firebase/auth"); const firebaseConfig = { /* 第三方服务的Firebase项目配置 */ }; const app = initializeApp(firebaseConfig); const auth = getAuth(app); // 用自定义令牌完成登录 const userCredential = await signInWithCustomToken(auth, customToken); const idToken = await userCredential.user.getIdToken(); - 第三方服务将ID令牌放在
Authorization: Bearer [idToken]请求头中传给你的后端,此时后端用verifyIdToken(idToken)即可正常验证。
方案2:直接验证自定义令牌的签名(仅特殊场景使用)
如果第三方服务无法集成Firebase Auth SDK,可直接验证自定义令牌的JWT签名:
- 安装依赖库:
npm install jsonwebtoken jwks-rsa - 编写验证逻辑替换原
verifyIdToken调用:const jwt = require('jsonwebtoken'); const jwksClient = require('jwks-rsa'); // 初始化JWKS客户端,获取Firebase公钥 const client = jwksClient({ jwksUri: 'https://www.googleapis.com/service_accounts/v1/jwk/securetoken@system.gserviceaccount.com' }); // 获取签名公钥 function getSigningKey(header, callback) { client.getSigningKey(header.kid, (err, key) => { const signingKey = key.publicKey || key.rsaPublicKey; callback(null, signingKey); }); } // 验证自定义令牌的异步方法 async function verifyCustomToken(token) { return new Promise((resolve, reject) => { jwt.verify(token, getSigningKey, { algorithms: ['RS256'] }, (err, decoded) => { if (err) reject(err); else resolve(decoded); }); }); } // 替换原验证代码 // const decodedToken = await admin.auth().verifyIdToken(idToken); const decodedToken = await verifyCustomToken(idToken);
关于jwt.io显示签名无效的说明
自定义令牌采用RS256非对称加密签名,jwt.io默认使用HMAC算法验证,因此会显示签名无效。你需要:
- 在jwt.io页面的「Algorithm」下拉框选择
RS256。 - 在「Public Key」输入框粘贴Firebase服务账号对应的公钥,即可验证签名有效。
内容的提问来源于stack exchange,提问作者Schorsch
相关产品推荐
相关产品推荐

