无法在 node/express 中验证 Cognito JWT 令牌

Unable to verify Cognito JWT token in node/express

提问人:micronyks 提问时间:11/17/2023 更新时间:11/17/2023 访问量:12

问:

auth.middelware.js

const jwt = require("jsonwebtoken");
const jwkToPem = require("jwk-to-pem");
const fetch = require("node-fetch");

let pems = {};                               // <########### pems object initialization and at some point in time, it get undefined

class AuthMiddleWare {

  constructor() {
    this.setUp();
  }

  verifyToken(req, res, next) {
    const token = req?.headers?.authorization;

    if (!token) {
       console.log("no tken")
    }

    let decodeJWT = jwt.decode(token, { complete: true });

    if (!decodeJWT) {
      console.log("error")
    }

    let kid = decodeJWT.header.kid;
    let pem = pems[kid];                            //%%%%%%% in some case pems become undefined automatically

    if (!pem) {                                     
      console.log("No PEM found")                   // <######## since there is no pem, it logs this error msg.
    }

    jwt.verify(token, pem, (err, decodedToken) => {
      if (err) {
       console.log("error occurred while verifying token", err);
      }
      next();
    });
  }

  async setUp() {
    const URL = `https://cognito-idp.eu-west-1.amazonaws.com/{environment.POOL_ID}/.well-known/jwks.json`

    try {
      const response = await fetch(URL);

      if (response.status !== 200) {
        throw new Error("request was not successful");
      }

      const data = await response.json();

      const { keys } = data;

      for (let index = 0; index < keys.length; index++) {
        const key = keys[index];
        const key_id = key.kid;
        const modulus = key.n;
        const exponent = key.e;
        const key_type = key.kty;
        const jwk = { kty: key_type, n: modulus, e: exponent };

        const pem = jwkToPem(jwk);

        pems[key_id] = pem;                   // <###### This store two keys/pems in pems object
      }
    } catch (error) {
      console.error("sorry couldn't fetch JWT", error);

    }
  }
};


module.exports = AuthMiddleWare;

索引.js

const express = require("express");
const app = express();
const AuthMiddleWare = require("../auth.middleware");
...
...
...

const auth = new AuthMiddleWare();                // initialize auth class so it will fetch PEMs


// routes are defined below

app.use(`api/products`, auth.verifyToken, productsRoute);    // auth.verifyToken
app.use(`api/customers`, auth.verifyToken, customerRoute);   // auth.verifyToken
...
...
...

app.listen(PORT, () => {
    console.log(`node-express server running in ${process.env.NODE_ENV} mode on ${PORT}`);
});

我的问题:

当我运行我的 node/express 应用程序时,它会 auth 类并运行函数并用两个或填充对象initializessetUppems ={}kidkey;

所以此时对象不是空的,它包含两个属性(键作为属性)。pems

现在,通过我的应用程序,当不同的 API(几乎 6-7 个 API 被调用)同时、随机地、在某个时间点时,对象会变得未定义。pems

现在,正如您在上面的代码中看到的那样,每个 api 都使用身份验证中间件,因此即使传递了正确的令牌,但由于对象变得未定义(不知道为什么它变得未定义),它也会停止我的应用程序。auth.verifyTokenpems

注意:它是随机发生的。对于任何 api,它都会失败。您无法再次以相同的方式重现此问题。 在随机时间未定义,调试它真的很难。pems

问题如何确保该对象不会未定义?pems

或者,如果有更好的方法,那么您可以提出建议。

节点.js Express JWT 中间件 PEM

评论


答: 暂无答案