简体   繁体   中英

AWS GET request with body rejected by CloudFront

I'm build an API using AWS SAM (Lambda & API Gateway) whose contract is defined by a 3rd party.

The 3rd party calls my API with a GET request that contains JSON in the body. However, when a request is sent to the API with a body it gets rejected by CloudFront.

This is the request:

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

This is the response:

<!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>

Checking the logs, the request never hits API Gateway or the Lambda function. However, if I remove the body from the request, then it hits the Lambda function and I get the appropriate error message from the API (telling the caller that the expected body is missing.)

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

I'm using basic configuration of API Gateway via a SAM template. This is the relevant section:

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 requests cannot contain a request body. Try using POST instead.

If you want to send limited data in a GET request, you can use query parameters.

You can see in the AWS Lambda Docs that this isn't possible here:

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

This is because the GET request that you submitted cannot take a payload and fails the request validation.

You could perhaps use an EC2 instance or other service that doesn't use API Gateway to handle the request.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM