我有一个问题,我有一个 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