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

如何使用Cloud Run和Swift验证Firebase ID Token?

问题分析与解决方案

核心问题排查

你遇到的「Firebase ID token has no 'kid' claim」错误,大概率是Token传递逻辑错误导致后端拿到了无效/空值的Token,其次可能是Firebase Admin SDK初始化或Token获取环节的问题。

1. 前端Token传递方式错误

你的前端代码将ID Token直接作为endpoint参数传递:

await web.webCall(endpoint: userIDToken)

这完全不符合接口调用逻辑——endpoint应该是后端接口的URL地址,而ID Token需要放在请求的Header(推荐)或请求体中传递,否则后端从req.body.idToken根本拿不到有效Token,自然会验证失败。

2. 前端默认传递空字符串风险

代码中用?? ""默认返回空字符串,如果getIDToken()获取失败,空字符串会被传给后端,空Token必然没有kid声明。

3. 后端可能未正确解析请求体

如果后端Express没有配置JSON解析中间件,req.body会是undefined,导致获取的Token无效。

分步修复方案

第一步:修正前端Token传递逻辑

将ID Token放在HTTP请求头(推荐用Authorization: Bearer <token>)或请求体中,同时处理Token获取失败的情况:

// 确保成功获取到Token再发送请求
guard let userIDToken = try await signIn.result?.user.getIDToken() else {
    print("Failed to retrieve ID Token")
    return
}

// 构建请求示例(用Authorization头传递)
guard let apiURL = URL(string: "https://your-cloud-run-service.com/api/verify-token") else {
    print("Invalid API URL")
    return
}

var request = URLRequest(url: apiURL)
request.httpMethod = "POST"
// 用Bearer Token格式放在Header
request.setValue("Bearer \(userIDToken)", forHTTPHeaderField: "Authorization")
// 发送请求(根据你的webCall方法调整参数)
await web.webCall(request: request)

第二步:修正后端Token验证逻辑

场景1:从Authorization头获取Token

// 先确保Express配置了JSON解析中间件(如果用请求体传的话需要)
app.use(express.json());

app.post('/api/verify-token', async (req, res) => {
    // 从Authorization头提取Token,去掉Bearer前缀
    const authHeader = req.headers.authorization;
    if (!authHeader || !authHeader.startsWith('Bearer ')) {
        return res.status(401).send("No valid ID token provided");
    }
    const idToken = authHeader.split(' ')[1];

    try {
        const decodedToken = await admin.auth().verifyIdToken(idToken);
        const uid = decodedToken.uid;
        console.log("Verified user UID:", uid);
        res.status(200).json({ uid: uid });
    } catch (error) {
        console.error("Token verification failed:", error);
        res.status(401).send("Invalid ID token");
    }
});

场景2:从请求体获取Token(如果前端用body传递)

确保前端请求体是JSON格式,且后端已配置express.json()中间件:

app.post('/api/verify-token', async (req, res) => {
    const idToken = req.body.idToken;
    if (!idToken) {
        return res.status(401).send("No ID token provided");
    }

    try {
        const decodedToken = await admin.auth().verifyIdToken(idToken);
        const uid = decodedToken.uid;
        console.log("Verified user UID:", uid);
        res.status(200).json({ uid: uid });
    } catch (error) {
        console.error("Token verification failed:", error);
        res.status(401).send("Invalid ID token");
    }
});

第三步:确认Firebase Admin SDK初始化正确性

在Cloud Run上可以直接使用默认应用凭据初始化,无需手动上传服务账号密钥:

const admin = require('firebase-admin');

// 自动使用Cloud Run的默认服务账号权限
admin.initializeApp();

如果手动初始化,需确保服务账号密钥正确,且账号拥有Firebase Auth Token Verifier权限。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 09:55:15