如何验证Google Bearer Token?Cloud Function鉴权报错求助
解决Google Chat云函数鉴权时"No pem found"错误
问题根源
你当前使用的google.auth.OAuth2的verifyIdToken方法是用来验证Google用户ID Token的,但Google Chat发送的是服务端令牌,两者属于不同类型的JWT,因此无法找到对应的PEM证书,导致验证失败。
解决方案
改用jsonwebtoken库手动验证Chat的服务令牌,同时从Google官方的公钥端点获取对应密钥进行签名验证:
1. 安装依赖
在云函数项目目录执行:
npm install jsonwebtoken axios
2. 修改代码实现
替换原有验证逻辑,实现Chat令牌的正确验证:
const jsonwebtoken = require('jsonwebtoken'); const axios = require('axios'); // 缓存Google Chat公钥,有效期1小时,避免重复请求 let cachedKeys = null; let cacheExpiry = 0; async function getChatPublicKeys() { const now = Date.now(); if (cachedKeys && now < cacheExpiry) { return cachedKeys; } const response = await axios.get('https://www.googleapis.com/service_accounts/v1/metadata/x509/chat@system.gserviceaccount.com'); cachedKeys = response.data; cacheExpiry = now + 3600 * 1000; return cachedKeys; } function getToken(bearerToken) { return bearerToken?.split(' ')[1] || ''; } async function verifyChatToken(token, expectedAudience) { if (!token) throw new Error('未提供令牌'); // 解码JWT头获取密钥ID(kid) const decodedHeader = jsonwebtoken.decode(token, { complete: true }).header; const keys = await getChatPublicKeys(); const publicKey = keys[decodedHeader.kid]; if (!publicKey) throw new Error(`找不到对应kid ${decodedHeader.kid}的PEM证书`); // 验证令牌签名、签发者、受众等信息 return jsonwebtoken.verify(token, publicKey, { algorithms: ['RS256'], issuer: 'chat@system.gserviceaccount.com', audience: expectedAudience, }); } exports.helloChat = async function helloChat(req, res) { try { const token = getToken(req.headers.authorization); // 替换为你的Chat应用OAuth客户端ID(在Cloud Console→API和服务→凭据中获取) // 或云函数的完整部署URL const expectedAudience = '你的Chat应用客户端ID或云函数URL'; const payload = await verifyChatToken(token, expectedAudience); // 鉴权通过,执行业务逻辑 res.status(200).send('鉴权成功'); } catch (error) { console.error('鉴权失败:', error.message); res.status(401).send('未授权'); } };
核心验证规则
- 签发者(issuer):必须为
chat@system.gserviceaccount.com,确保请求来自Google Chat官方服务 - 受众(audience):填写你的Chat应用的OAuth客户端ID,或云函数的完整部署URL,确保令牌是发给你的服务的
- 签名算法:固定使用
RS256,与Chat令牌的算法一致 - 公钥缓存:缓存公钥减少重复请求,提升验证性能
内容的提问来源于stack exchange,提问作者prismo
相关产品推荐
相关产品推荐

