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

如何验证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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 23:16:31