Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AWS API Gateway CORS ok for OPTIONS, fail for POST

I've looked at the other related questions on SO but this seems different. In fact, my question is very similar to this one, except I don't have the 400 status issue.

The set up:

  • lambda function through API Gateway
  • Authorization: None, API KEY Required: false
  • deploying to stage: test

  • 1 resource, 1 POST method integrating the lambda.

  • Calling the POST endpoint directly e.g. with curl always returns 200 (with/without payload, bad payload, etc.) - so that's different from the referenced question.

I've used the "Enable CORS" option - I've tried applying this option on both the resource, and the POST request (and deploying the API afterwards).

In API GW, I can see Access-Control-Allow-Origin listed in 200 Response Headers under POST method - Method Response area.

Result: Calling the endpoint from client code in Chrome, OPTIONS passes but POST fails due to missing Access-Control-Allow-Origin header.

In curl: OPTIONS call

curl -X OPTIONS -H "Access-Control-Request-Method: POST" \
     -H "Access-Control-Request-Headers: Content-Type" \
     -H "Origin: http://example.com" --verbose <endpoint>

the response is:

< HTTP/1.1 200 OK
< Content-Type: application/json
...
< Access-Control-Allow-Headers: Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token
< Access-Control-Allow-Methods: POST,OPTIONS
< Access-Control-Allow-Origin: *
...

but with POST:

curl -X POST -d '{}' -H "Content-Type: application/json" \
     -H "Origin: http://example.com" --verbose <endpoint>

it returns:

< HTTP/1.1 200 OK
< Content-Type: application/json
...

and the response json body - but no Access-anything header.

What else can I check?

like image 291
bebbi Avatar asked Oct 20 '16 08:10

bebbi


1 Answers

The problem has been that the API gateway has called my lambda function using the "Lambda Proxy Integration" option checked.

I believe this is activated by default when adding a API gateway trigger to a newly created lambda function.

When inside the API Gateway - Resource - Method view, the "Integration Response" box is greyed out and it seems there's no way (even for the Enable CORS function) to add a Access-Control-Allow-Origin header there, which according to @Abhigna_Nagaraja is required.

Solution: If using "Lambda Proxy Integration", add the 'Access-Control-Allow-Origin': '*' header to your lambda function.

Even better: in the same view - Integration Request, turn off "Lambda Proxy Integration" and Enable CORS again (deploy afterwards).

(Then, in the callback, you'll have to return just the payload json instead of the { statusCode, headers, body } object.)

Update:

Some useful reads if you're unsure whether to return request response status information in http status codes or in the json payload:

http status vs json status

json status standards

like image 60
bebbi Avatar answered Oct 19 '22 05:10

bebbi