What I did to enable CORS on AWS API Gateway

What I did to enable CORS on AWS API Gateway

·

5 min read

Introduction

I've been using AWS API Gateway and setting up CORS has been taking up a lot of my time, so I'd like to make a note of it for those who may do the same thing.

CORS headers are not attached…

If you're using API Gateway's Lambda Proxy Integration - LPI then just Enable CORS doesn't give you a nice CORS-related header unlike other integration methods.

image.png

I went to Integration Response to see what kind of response headers are set, but it's grayed out, I guess CORS headers are set here if it's not LPI.

image.png

[¹]: I think the Method Response might be able to do something about the headers, but I haven't looked into it in detail.

How can I do this right?

If you're using LPI and want to allow CORS, you can do the following three things (maybe)

  1. Return CORS header on Lambda side
  2. Set Authorization to NONE in OPTIONS so that you can use Preflight[²].
  3. Add CORS header to the error response as well, so that the error response is not rejected by CORS.

[²]: Is this a good idea? If there's a better way, someone please let me know :).

1. Return headers in the Lambda code

Put the header in the code like:

def lambda_handler(event:, context:) 
  :
  :
   { 
     statusCode: 200,
     headers: {
     "Access-Control-Allow-Headers": "Content-Type",
     "Access-Control-Allow-Origin": '*',
     "Access-Control-Allow-Methods": "OPTIONS,POST,GET"
     },
     body: JSON.generate(list_project(table))
   }
  :
  :
end

2. Set Authorization of OPTIONS to NONE

API GatewayAPIOPTIONS

image.png

Add CORS header in error response

If you only do #1, responses that do not reach the lambda - e.g. errors at API Gateway - will not have headers thus will be blocked by CORS in the browser. If this happens, you may not know what's going on, and it may look like a CORS error while it's just an authentication error.

API GatewayAPIGateway ResponseDefault 4xx and Default 5xx.

image.png

What does the official documentation say?

If you read it carefully, it will tell you how, but it will not tell you why.

  • CORS itself, whether it is a simple request or not, and what kinds of things are covered by CORS can be found here which is good.
  • The specific configuration method is here, but I think the following description and others are suspicious.

Important: Applying the above steps to the ANY method of the proxy integration will not set the proper CORS headers. Instead, the backend should return an appropriate CORS header, such as Access-Control-Allow-Origin. I've actually tried this, but even if you don't have ANY, you won't get a CORS header…

Enable CORS support for Lambda or HTTP proxy integration For Lambda proxy integrations or HTTP proxy integrations, you can continue to set the OPTIONS response header as required by the API Gateway. However, proxy integrations do not return an integration response, so the backend will return Access-Control-Allow-Origin and Access-Control-Allow-Headers.

Only OPTIONS seems to be doing a good job, but why only OPTIONS?

image.png

Oh, and API Gateway changes are not reflected unless you deploy, so it's easy to accidentally forget and get stuck there too. Also, it takes a few minutes for deploy to reflect the changes, so wait patiently.

Okey, now it should handle CORS request. Enjoy!

Cheers,