【问题标题】:AWS GET request with body rejected by CloudFront正文被 CloudFront 拒绝的 AWS GET 请求
【发布时间】:2019-05-16 03:36:21
【问题描述】:

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

第 3 方使用正文中包含 JSON 的 GET 请求调用我的 API。但是,当请求通过正文发送到 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 Gateway 或 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 Gateway 的基本配置。这是相关部分:

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

【问题讨论】:

  • this post。根据 RFC,这是非法的。
  • 我正在订阅第 3 方的 Webhook,第 3 方发出此请求以验证我的 API 是否正在响应。我理解对包含正文的 GET 请求的反对意见,但我无法控制它。如果没有解决方法,那么我唯一的选择是将我的 API 完全移出 AWS。
  • 我理解您的沮丧,但 AWS 正在实施该标准。尝试在 EC2 上创建一些代码,也许您可​​以找到允许它的东西。我知道你被夹在中间,但除了告诉第 3 方他们正在破坏事情之外,这将是一个很难解决的问题。
  • 我刚刚向自己证明,至少在带有 JAX-RS 的 Java 中,我可以从 GET 调用中获取正文。这有点令人费解,但可以做到。

标签: amazon-web-services aws-lambda aws-api-gateway amazon-cloudfront


【解决方案1】:

GET 请求不能包含请求正文。尝试改用POST

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

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

https://docs.aws.amazon.com/apigateway/latest/developerguide/getting-started-lambda-non-proxy-integration.html

这是因为您提交的 GET 请求无法获取有效负载并且无法通过请求验证。

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

【讨论】:

  • 谢谢,但是第 3 方指定了 API 合同,所以我无法更改请求的样子。我不能发送 POST 或只是查询参数。
  • 那么第三方需要更改合约。大多数服务器不支持带有正文的 GET 请求。这是相当标准的做法。
  • 您可以在此处找到有关该主题的更多详细信息:stackoverflow.com/questions/978061/http-get-with-request-body
  • 值得注意的是,HTTP 规范中并没有禁止使用 GET 方法的主体,实际上它通常与某些 API 一起使用,请参阅:elastic.co/guide/en/elasticsearch/reference/current/…
  • 虽然这可能是真的,但这个问题是关于不允许它的 API 网关。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-30
  • 2021-09-07
  • 2021-03-06
相关资源
最近更新 更多