如何保护由Google Chat调用的Google Cloud Function?
限制Google Chat访问Cloud Function并验证JWT签名
核心思路
因为Google Chat不属于你的Cloud项目,无法通过内部流量限制或IAM服务账号直接控制访问,所以只能在Cloud Function内部验证请求携带的JWT,以此确保请求来自Google Chat。网络层面无法通过防火墙规则限制,因为Google Chat的出口IP是动态且未公开固定段的。
验证Google Chat JWT的具体步骤
1. 提取请求中的JWT
从请求头的authorization字段中提取Bearer Token,格式为Bearer <token>,需要去掉前缀只保留Token部分。
2. 获取Google的公钥用于签名验证
Google的OAuth 2.0公钥托管在https://www.googleapis.com/oauth2/v3/certs,这个地址返回的JSON包含多个公钥,每个公钥对应一个kid(与JWT头中的kid匹配)。
3. 验证JWT的关键字段
验证时必须检查以下字段,确保请求合法:
iss:必须等于chat@system.gserviceaccount.com,确认请求发起方是Google Chataud:匹配你收到的JWT中的aud值(你的例子中是939021344830,通常是Chat应用或Cloud项目的关联ID)exp:必须大于当前时间,确保Token未过期iat:确保Token的签发时间合理,避免伪造的过期Token
代码示例(Node.js)
const jwt = require('jsonwebtoken'); const fetch = require('node-fetch'); exports.googleChatHandler = async (req, res) => { // 提取并校验Token是否存在 const authHeader = req.headers.authorization; if (!authHeader || !authHeader.startsWith('Bearer ')) { return res.status(403).send('无合法授权'); } const token = authHeader.split(' ')[1]; try { // 获取Google公钥 const certsRes = await fetch('https://www.googleapis.com/oauth2/v3/certs'); const certs = await certsRes.json(); // 验证Token签名及字段 const decoded = jwt.verify(token, certs, { issuer: 'chat@system.gserviceaccount.com', audience: '939021344830' // 替换为你实际的aud值 }); // 验证通过,处理业务逻辑 console.log('合法请求,来源:', decoded.iss); res.status(200).json({ text: '已收到Chat请求' }); } catch (err) { console.error('Token验证失败:', err.message); return res.status(403).send('授权无效'); } };
额外说明
- 无需修改Cloud Function的流量设置(保持“允许所有流量”即可),非法请求会被JWT验证步骤拦截
- 公钥地址是Google官方维护的,无需自行存储或更新公钥,每次请求动态获取即可保证正确性
内容的提问来源于stack exchange,提问作者emrys57
相关产品推荐
相关产品推荐

