我有一个NodeJS机器人,它使用HTTPs端点连接到Google Chat。我正在使用快递来接收请求。我需要验证所有请求均来自Google,并希望使用Google随请求发送的承载令牌来执行此操作。
我的问题是我正在努力寻找一种方法来验证令牌。
我已经捕获了令牌,并尝试对https://oauth2.googleapis.com/tokeninfo?id_token=ey ...(其中ey ...是令牌的开头)进行GET reuqes。
哪个返回:
"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发现了这一点,正在研究如何使用它。那孩子匹配我得到的那个。
答案 0 :(得分:0)
最终解决了。
您需要点击:https://www.googleapis.com/service_accounts/v1/metadata/x509/chat@system.gserviceaccount.com以获取一个JSON文件,其中包含链接到其KID的密钥。
然后,当请求到达时,使用jsonwebtoken(NPM)解码令牌并从标头中提取KID。
使用KID在上述网站的响应中找到匹配的公钥,然后使用验证功能确保令牌与公钥匹配。
您还需要传递观众和发行者的选项进行验证,以确认这是您攻击机器人的特定服务帐户。
答案 1 :(得分:0)
上述解决方案可能适用于 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