【问题标题】:Verify JWT from Google Chat POST request从 Google Chat POST 请求验证 JWT
【发布时间】: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 发现了这个,正在研究如何使用它。这个孩子和我得到的那个很相配。

【问题讨论】:

    标签: node.js google-api jwt


    【解决方案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 在上述网站的响应中找到匹配的公钥,然后使用验证功能确保令牌与公钥匹配。

      您还需要传递受众和颁发者选项以进行验证,以验证是您的特定服务帐户击中了机器人。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-03-23
        • 2019-03-26
        • 1970-01-01
        • 2018-11-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多