在 AWS 上,是否可以将 CloudFront 代理请求发送到 API 网关,同时维护请求的查询字符串?

在 AWS 上,是否可以将 CloudFront 代理请求发送到 API 网关,同时维护请求的查询字符串?

我有一个配置了多个来源的 CloudFront 分发,包括一个 API 网关部署。

我正在尝试在 CloudFront 上创建一个行为,以便任何收到的/api/*路径请求都将被重定向到 API 网关,我所做的只是创建一个新的行为,其路径模式为,/api/*Origin 为我提到的 API 网关部署。这可行,但是任何包含查询字符串的请求(例如/api/data?since=2020-01-01)都会导致向 API 网关发出没有查询字符串的请求,即到达 API 网关的只是/api/data

为了解决这个问题,我尝试设置缓存策略为Managed-CachingOptimized(甚至为Managed-CachingDisabled) 和源请求策略为Managed-AllViewer,但随后 CloudFront 开始完全忽略该行为并处理下一个行为,该行为恰好是 S3 存储桶。请求发送到 S3 存储桶后,我收到 404 返回,因为那里没有这样的密钥。

我也尝试使用“旧版缓存设置”,但同样的问题仍然存在。

是否可以使用 CloudFront 和 API GW 实现此“代理”?如果可以,我该怎么做?

谢谢

答案1

这也让我感到困惑,查询字符串和标头都如此,例如Authorization

但是,文档指出要将Authorization标头传递到原点,必须将其用作缓存键:

缓存键设置指定 CloudFront 在缓存键中包含的查看器请求中的值。这些值可以包括 URL 查询字符串、HTTP 标头和 Cookie。包含在缓存键中的值会自动包含在 CloudFront 发送到源的请求(称为源请求)中。

注意:您不能使用源请求策略来转发授权标头。标头必须是缓存键的一部分,以防止缓存满足未经授权的请求。如果您尝试创建转发授权标头的源请求策略,CloudFront 将返回 HTTP 400 错误。

此外,请注意,与来源请求策略相关Managed-AllViewer,问题似乎是将Host标头转发到 API 网关;请参阅https://github.com/aws-cloudformation/cloudformation-coverage-roadmap/issues/571#issuecomment-792051286即我们不能将其用于Managed-AllViewerAPI 网关来源。

  1. https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/controlling-the-cache-key.html
  2. https://aws.amazon.com/premiumsupport/knowledge-center/cloudfront-authorization-header/

作为 CDKcloudfront.Distribution()构造的一部分:

const apiCachePolicy = new cloudfront.CachePolicy(this, 'ApiCachePolicy', {
        headerBehavior: cloudfront.CacheHeaderBehavior.allowList('authorization'),
        queryStringBehavior: cloudfront.CacheQueryStringBehavior.all(),
        cookieBehavior: cloudfront.CacheCookieBehavior.none(),
        minTtl: Duration.minutes(0),
        maxTtl: Duration.minutes(1),
        defaultTtl: Duration.minutes(0),
        enableAcceptEncodingGzip: true,
        enableAcceptEncodingBrotli: true,
    });

答案2

我有一个类似的要求,即通过 cloudfront 访问 AWS GW 上的几个 API。

  1. 首先,我创建了几个带有路径变量的 API,例如用于 PUT 和 GET 方法的 /users/{users-id}
  2. 在 API GW 中创建自定义域(使用子域和 SSL 证书)并创建 API 映射(一个 API 映射到 asset1,另一个 API 映射到 asset2)
  3. 创建自定义原点作为 api 自定义域,如 api.xyz.com,并创建自定义映射路径 asset1 的行为以重定向到该 API
  4. 后端 API 在 ecs 容器上运行,我将其映射为 API GW 中的目标
  5. 然后能够通过来自 cloudfront 的根域代理该 API,并使用带有资源路径(如“http:///asset1/users/{user-id}”)的映射名称调用 API,方法是将用户 ID 替换为所需值。

但不幸的是,我无法从 cloudfront 实现 /api/* 映射,因为它期望 api 路径必须存在于 API GW 上,而 API GW 不支持使用自定义域的 api/asset1 等多级映射。

相关内容