从 Google Chat POST 请求验证 JWT
Posted
技术标签:
【中文标题】从 Google Chat POST 请求验证 JWT【英文标题】:Verify JWT from Google Chat POST request 【发布时间】:2019-09-05 22:31:23 【问题描述】:我有一个使用 HTTPs 端点连接到 Google Chat 的 NodeJS 机器人。我正在使用快递接收请求。我需要验证所有请求都来自 Google,并希望使用 Google 随请求发送的承载令牌来执行此操作。
我的问题是我正在努力寻找验证令牌的方法。
我已捕获令牌并尝试对https://oauth2.googleapis.com/tokeninfo?id_token=ey... 进行 GET 请求(其中 ey... 是令牌开始)。
返回:
"error": "invalid_token",
"error_description": "Invalid Value"
我已经尝试过 Google 推荐的方法:
var token = req.headers.authorization.split(/[ ]+/);
client.verifyIdToken(
idToken: token[1],
audience: JSON.parse(process.env.valid_client_ids)
).then((ticket) =>
gchatHandler.handleGChat(req.body, res);
).catch(console.error);
并得到以下错误:
错误:找不到信封的 pem:"alg":"RS256","kid":"d...1","typ":"JWT"
知道我应该从这里去哪里吗?
编辑:https://www.googleapis.com/service_accounts/v1/metadata/x509/chat@system.gserviceaccount.com 发现了这个,正在研究如何使用它。这个孩子和我得到的那个很相配。
【问题讨论】:
【参考方案1】:上述解决方案可能适用于 Google Chat,但根据我的经验,Google 服务(例如 Google Tasks)使用 OIDC 令牌,可以使用 verifyIdToken
函数进行验证。
在此处添加我的解决方案,因为您的问题/答案是我能找到的最接近我的问题的东西
所以,如果您需要使用自己的代码签署请求
在客户端,使用 OIDC 令牌发送请求
import URL from 'url';
import GoogleAuth from 'google-auth-library';
// will use default auth or GOOGLE_APPLICATION_CREDENTIALS path to SA file
// you must validate email of this identity on the server!
const auth = new GoogleAuth();
export const request = async (url, ...options) =>
const targetAudience = new URL(url as string).origin;
const client = await auth.getIdTokenClient(targetAudience);
return await client.request(...options, url);
;
await request( url: 'https://my-domain.com/endpoint1', method: 'POST', data: )
在服务器上,验证 OIDC(Id 令牌)
const auth = new OAuth2Client();
const audience = 'https://my-domain.com';
// to validate
const token = req.headers.authorization.split(/[ ]+/)[1];
const ticket = await auth.verifyIdToken(idToken: token, audience );
if (ticket.getPayload().email !== SA_EMAIL)
throw new Error('request was signed with different SA');
// all good
阅读更多关于Google OpenID Connect Tokens
【讨论】:
【参考方案2】:最终解决了。
您需要点击:https://www.googleapis.com/service_accounts/v1/metadata/x509/chat@system.gserviceaccount.com 以获取一个 JSON 文件,其中包含链接到其 KID 的密钥。
然后当请求到达时,使用 jsonwebtoken (NPM) 对 token 进行解码并从 header 中提取 KID。
使用 KID 在上述网站的响应中找到匹配的公钥,然后使用验证功能确保令牌与公钥匹配。
您还需要传递受众和颁发者选项以进行验证,以验证是您的特定服务帐户击中了机器人。
【讨论】:
以上是关于从 Google Chat POST 请求验证 JWT的主要内容,如果未能解决你的问题,请参考以下文章
Google PubSub / Gmail Webhook:发送电子邮件时始终从 PubSub 接收多个 POST 请求
请求的身份验证范围不足 - 在 Flutter 中使用 Firebase 从 Google 登录获取生日时出错
Google App Script Web App GET 和 POST 请求被 CORS 策略阻止
如何使用python请求将经过身份验证的POST请求编码到API?