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.
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.
[¹]: 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)
- Return CORS header on Lambda side
- Set
Authorization
toNONE
inOPTIONS
so that you can use Preflight[²]. - 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 Gateway
→API
→OPTIONS
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 Gateway
→API
→Gateway Response
→Default 4xx
and Default 5xx
.
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
?
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,