如何从 Google pub/sub push 验证 JWT 令牌找不到用于信封的 pem

问题描述

上下文

我正在按照 Google's RTDNs 指南启用实时开发者通知。我已经成功创建了主题订阅,并收到了发送到我创建的 API 的推送通知。我现在想验证和验证这些消息。为此,我正在关注 this guide on Authentication and Authorization。他们的开发者文档 herehere一个看似有用的例子。

问题

按照上述资源进行操作后,我收到以下错误

Error: No pem found for envelope: {"typ":"JWT","alg":"HS256"}

相关代码

const authClient = new oauth2client();
// ... 
app.post('/pubsub/authenticated-push',jsonBodyParser,async (req,res) => {

  // Verify that the push request originates from Cloud Pub/Sub.
  try {
    // Get the Cloud Pub/Sub-generated JWT in the "Authorization" header.
    const bearer = req.header('Authorization');
    const [,token] = bearer.match(/Bearer (.*)/);

    // Verify and decode the JWT.
    // Note: For high volume push requests,it would save some network
    // overhead if you verify the tokens offline by decoding them using
    // Google's Public Cert; caching already seen tokens works best when
    // a large volume of messages have prompted a single push server to
    // handle them,in which case they would all share the same token for
    // a limited time window.

    // verifyIdToken is failing here with the `No pem found for envelope` error
    const ticket = await authClient.verifyIdToken({
      idToken: token,audience: 'example.com',});

    // ...

  } catch (e) {
    res.status(400).send('Invalid token');
    return;
  }

  res.status(200).send();
});

问题

由此,我假设我需要一些公钥。

  1. 我从哪里获得上述公钥?
  2. 我应该把所说的公钥放在哪里,以便用它初始化谷歌客户端?
  3. 如何生成示例 JWT 来测试我的端点?

编辑

我能够在 their code here 中找到此错误的根源:

    if (!Object.prototype.hasOwnProperty.call(certs,envelope.kid)) {
      // If this is not present,then there's no reason to attempt verification
      throw new Error('No pem found for envelope: ' + JSON.stringify(envelope));
    }

但是,我已经验证 kid 属性确实存在于解码对象中:

{"alg":"RS256","kid":"7d680d8c70d44e947133cbd499ebc1a61c3d5abc","typ":"JWT"}

解决方法

结果 kid 无效,因此抛出 No pem found for envelope 错误。一旦提供了有效的 kid,错误就不再存在。