Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AWS APIGateway CORS for Lambda Proxy does not apply

I have set up a APIGateway resource with a POST Lambda Proxy method, and an OPTIONS method for CORS headers.

The OPTIONS method returns these headers:

$ curl -i -X OPTIONS https://xxxxxxxxx.execute-api.eu-central-1.amazonaws.com/dev/endpoint1

HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 0
Connection: keep-alive
Date: Sat, 18 Feb 2017 17:07:17 GMT
x-amzn-RequestId: xxxx
Access-Control-Allow-Origin: *
Access-Control-Allow-Headers: Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token
Access-Control-Allow-Methods: POST,OPTIONS
X-Cache: Miss from cloudfront
Via: 1.1 xxxx.cloudfront.net (CloudFront)
X-Amz-Cf-Id: xxxx==

Yet when I call the POST endpoint with the generated Javascript SDK, the Chrome browser console shows this error:

XMLHttpRequest cannot load https://xxxx.execute-api.eu-central-1.amazonaws.com/dev/endpoint1.
No 'Access-Control-Allow-Origin' header is present on the requested resource.
Origin 'http://localhost:8080' is therefore not allowed access.

as well as Firefox:

Cross-Origin Request Blocked: 
The Same Origin Policy disallows reading the remote resource at https://xxxx.execute-api.eu-central-1.amazonaws.com/dev/endpoint1.
(Reason: CORS header ‘Access-Control-Allow-Origin’ missing).

Why is my CORS header not taken into account? Are additional changes of the POST method settings required?

like image 419
Appleshell Avatar asked Feb 18 '17 17:02

Appleshell


2 Answers

It seems to be required to add the headers manually in the lambda function.

In the case of NodeJS the script would look like this:

context.succeed({
    "statusCode": 200,
    "headers": {
        "X-Requested-With": '*',
        "Access-Control-Allow-Headers": 'Content-Type,X-Amz-Date,Authorization,X-Api-Key,x-requested-with',
        "Access-Control-Allow-Origin": '*',
        "Access-Control-Allow-Methods": 'POST,GET,OPTIONS'
    },
    "body": JSON.stringify(response)
})
like image 75
Appleshell Avatar answered Oct 30 '22 10:10

Appleshell


A better approach would be to use the API Gateway to enrich the payload from your lambda with CORS related headers as described here: https://kennbrodhagen.net/2015/12/02/how-to-access-http-headers-using-aws-api-gateway-and-lambda/

This is a much more scalable and less error prone approach.

like image 32
JTango18 Avatar answered Oct 30 '22 11:10

JTango18