0

我有一个问题,我有一个 lambda 处理程序,它调用一个中间件,该中间件解码 JWT 令牌并验证它并修改请求以添加解码的令牌,当我在本地调用我的 lambda 时一切正常,但在部署到 AWS 时它超时。我正在使用 SAM cli 工具在 AWS 中进行部署和资源创建。尝试对我的代码使用@middy/do-not-wait-for-empty-event-loop 但没有运气:(

处理程序代码:

const myHandler = middy(async (event) => {
    const envVars = validateEnvVars(process.env);
    let res;
    try {
        res = {
            statusCode: 200,
            body: JSON.stringify({ data: 'abc-xyz' })
        };
        return res;
    } catch (err) {
        res = {
            statusCode: StatusCodes.INTERNAL_SERVER_ERROR,
            message: err.stack,
        }
        return res;
    }
});

getSQSSO.use(doNotWaitForEmptyEventLoop({ runOnError: true }))
        .use(decodeJWT());
        
 
module.exports = { myHandler };

中间件解码JWT:

const getJwksClient = (jwksUri) => {
  if (!jwksClientCache.has(jwksUri)) {
    jwksClientCache.set(jwksUri, jwksClient({ jwksUri }));
  }

  return jwksClientCache.get(jwksUri);
};

const decodeJWT = (opts) => {
  const decodeJWTBefore = async (request) => {
      const { Authorization } = request.event.headers;
      if (typeof Authorization !== 'string') { 
        throw new Error(StatusCodes.UNAUTHORIZED);
      }
      const [tokenType, token] = Authorization.split(' ');
      if (tokenType !== 'Bearer') throw new Error(StatusCodes.UNAUTHORIZED);
      // Decode Token
      const decodedToken = jwt.decode(token);
      // Get client from cache and add to cache if not yet cached
      const client = getJwksClient(`${decodedToken.iss}/protocol/openid-connect/certs`);
      const jwt_header = JSON.parse(Buffer.from(token.split('.')[0], 'base64').toString());
      
      const getKey = (header) => { 
        return new Promise((resolve, reject) => {
          client.getSigningKey(header.kid, (err, key) => {
            if(err) reject(err)
            resolve(key.publicKey);
          });
        });
      };
     console.debug('I work fine until here, probably await is causing the issue');
      let publicKey;
      try {
        publicKey = await getKey(jwt_header); // -----  Stucks here, logs before this get printed out in CloudWatch ----
      } catch(err) {
        console.error(err);
        throw new Error(err);
      }
      const verified = jwt.verify(token, publicKey, {});
  
      request.event.auth = verified;
  };

  const decodeJWTBeforeOnError = async (request) => {
    return {
      statusCode: request.error.statusCode || StatusCodes.INTERNAL_SERVER_ERROR,
      message: JSON.stringify(request.error) || 'Something went wrong, unknown error',
    };
  };

  return {
    before: decodeJWTBefore,
    onError: decodeJWTBeforeOnError
  }
    
};

即使在使用 @middy/do-not-wait-for-empty-event-loop 中间件之后,AWS 中的 Lambda 也会超时,尽管在日志中我仍然可以看到 request.context.callbackWaitsForEmptyEventLoop = false

$Latest
"context": {
        "callbackWaitsForEmptyEventLoop": false,
        "functionVersion": "$LATEST",
        "functionName": "myhandler-xxx",
        "memoryLimitInMB": "128",
        ...
}
DEBUG I work fine until here, probably await is causing the issue

Node.js 版本:v14.17.6

Middy 版本:v2.5.1

@middy/do-not-wait-for-empty-event-loop: v2.5.1

AWS 开发工具包版本:v2.799.0

4

0 回答 0