正文被 CloudFront 拒绝的 AWS GET 请求

AWS GET request with body rejected by CloudFront

我正在使用 AWS SAM(Lambda 和 API 网关)构建一个 API,其合同由第 3 方定义。

第 3 方使用 GET 请求调用我的 API,正文中包含 JSON。但是,当一个请求被发送到 API 时,它会被 CloudFront 拒绝。

这是请求:

curl -X GET -H "Content-Type: application/json" --data '{"hello":"world"}' https://my-api.execute-api.us-east-2.amazonaws.com/Prod/my-api

这是回复:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<HTML>
    <HEAD>
        <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
        <TITLE>ERROR: The request could not be satisfied</TITLE>
    </HEAD>
    <BODY>
        <H1>403 ERROR</H1>
        <H2>The request could not be satisfied.</H2>
        <HR noshade size="1px">
Bad request.


        <BR clear="all">
        <HR noshade size="1px">
        <PRE>
Generated by cloudfront (CloudFront)
Request ID: 1p0St_-e3noQL-2uMxeB_2I6lkMr1mg5afvxJRmVpCdnG67Vgnhj9w==
</PRE>
        <ADDRESS></ADDRESS>
    </BODY>
</HTML>

检查日志,请求从未命中 API 网关或 Lambda 函数。但是,如果我从请求中删除正文,那么它会触发 Lambda 函数,并且我会从 API 中收到相应的错误消息(告诉调用者缺少预期的正文。)

curl -X GET -H "Content-Type: application/json" https://my-api.execute-api.us-east-2.amazonaws.com/Prod/my-api

我正在通过 SAM 模板使用 API 网关的基本配置。这是相关部分:

MyApiFunction:
  Type: AWS::Serverless::Function
  Properties:
    CodeUri: bin/main.zip
    Handler: main
    Runtime: go1.x
    Tracing: Active
    Role: !Sub ${MyApiLambdaExecutorRole.Arn}
    Events:
      CatchAll:
        Type: Api
        Properties:
          Path: /my-api
          Method: GET

GET 请求不能包含 CloudFront 上的请求正文。请尝试使用 POST

如果要在 GET 请求中发送有限的数据,可以使用查询参数。

您可以在 AWS 文档中看到,这在此处是不可能的:

https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/RequestAndResponseBehaviorCustomOrigin.html#RequestCustom-get-body

If a viewer GET request includes a body, CloudFront returns an HTTP status code 403 (Forbidden) to the viewer.

您或许可以使用 EC2 实例或其他不使用 API 网关的服务来处理请求。