user1283776
user1283776

Reputation: 21764

Can GET but not POST to a Lambda via API Gateway. Why?

Below is the request the client makes. The GET request is a success, but the POST request gives an error.

fetch('api/public/libraries/sign-out-discourse', {
    method: 'GET', // or 'POST'
    headers: new Headers([
        ['Accept', 'application/json'],
        ['Content-Type', 'application/json'],
        ['Authorization', jwtToken],
    ]),
})

Here is the error from the POST request:

HTTP/1.1 403 Forbidden
Server: CloudFront
Date: Fri, 05 Oct 2018 08:50:14 GMT
Content-Type: text/html
Content-Length: 694
Connection: keep-alive
X-Cache: Error from cloudfront
Via: redacted
X-Amz-Cf-Id: redacted

<!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">
This distribution is not configured to allow the HTTP request method that was used for this request. The distribution supports only cachable requests.

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

What I have tried

In CloudFront I have chosen behaviors -> edit -> Allowed HTTP Methods: GET, HEAD, OPTIONS, PUT, POST, PATCH, DELETE. I have invalidated caches since making this chance in the unlikely case that AWS stores settings in the CloudFront cache somehow.

In API Gateway graphical, I have enabled CORS for the resource. I have redeployed the API since making this change.

Other debugging

curl -X POST API_ENDPOINT returns the same error as calling the endpoint with POST from my application.

Upvotes: 0

Views: 2427

Answers (1)

Matt D
Matt D

Reputation: 3496

If you are using Lambda Proxy integration, you need to provide the CORS header in the response, API Gateway will not do that for you for a POST request.

var response = {
    statusCode: 200,
    headers: {
        "Access-Control-Allow-Origin" : "*",
        "Access-Control-Allow-Credentials" : true
    },
    body: JSON.stringify({"message":"Success"})
}
callback(null, response);

Upvotes: 1

Related Questions