我尝试使用
aws-jwt-verify
npm 包获取 aws-cognito JWK 来验证 JWT 令牌,但不幸的是它随机失败。
我有一个节点/express 应用程序,我将其(整个应用程序)部署到一个 lambda 函数。所以基本上应用程序启动如下 lambda 函数(生产),
服务器.js
const awsServerlessExpress = require("aws-serverless-express");
const app = express();
const server = awsServerlessExpress.createServer(app)
const verifyToken = require("./src/middlewares/auth.middleware"); // auth middleware to verify token
app.use(`${api/products`, verifyToken, productsRoute);
// other routes
if (NODE_ENV === "local") { // for development
const server = app.listen(PORT, () => {
logger.debug(`node-express server running in ${process.env.NODE_ENV} mode on ${PORT}`);
});
} else { // For production
module.exports.handler = (event, context) => { // For lambda execution start here
awsServerlessExpress.proxy(server, event, context);
}
}
auth.middleware.js
const { CognitoJwtVerifier } = require('aws-jwt-verify');
const { SimpleJwksCache } = require("aws-jwt-verify/jwk");
const { SimpleJsonFetcher } = require("aws-jwt-verify/https");
const verifyToken = async (req, res, next) => { // for requested route, it executes
const token = req?.headers?.authorization;
let decodedToken;
const verifier = CognitoJwtVerifier.create(
{
userPoolId: enviornment.cognito.userPoolId,
tokenUse: 'id',
clientId: enviornment.cognito.appClientId,
},
{
jwksCache: new SimpleJwksCache({ // I hope, I'm caching it so it doesn't end up fetching JWKs again n again. Correct me if my understanding is wrong
fetcher: new SimpleJsonFetcher({
defaultRequestOptions: {
responseTimeout: 5000,
},
}),
}),
}
);
decodedToken = await verifier.verify(token);
...
...
next();
}
有时有效,有时无效。无法准确判断何时失败。
无法获取 https://cognito-idp.#region.amazonaws.com/#region_#clientId/.well-known/jwks.json:响应超时(3000 毫秒后)
类似的问题从未得到解答:npm 包“aws-jwt-verify”无法在 Windows ec2 机器上获取 jwks 文件
这是一个非常短的超时,只有 3 秒。作为快速更改,您可以通过延长 responseTimeout 来扩展它。
更广泛的问题是,每个 API 请求都会创建一个无服务器 lambda,因此无法使用内存缓存。这是 lamdbas 的真正缺点。
默认情况下,每个 API 请求都会调用 JWKS 端点,从而将负载加载到关键组件授权服务器上。因此,您有责任防止这种情况发生。
您可以通过自定义 JWT 库的缓存接口来实现这一点。我在使用 JwksRetriever 和 DynamoDB 缓存的代码示例中做了类似的事情。