I have been fighting CORS for a while now and I have run out of ideas. I have a AWS::Serverless::HttpApi
deployed through SAM. This API has only one endpoint for now, it takes a POST request to /auctions
. Testing in PostMan it works, but of course testing anywhere else throws the dreaded preflight failed
error. The past couple of day I have been trying different things and nothing has worked. Here is the current state of my template.yaml
:
Resources:
AdminApi:
Type: AWS::Serverless::HttpApi
Properties:
CorsConfiguration:
AllowMethods:
- GET
- POST
- OPTIONS
AllowOrigins:
- "*"
AllowHeaders:
- "*"
OptionsFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: ./src
Handler: handlers/options.lambda_handler
Runtime: python3.9
Events:
ApiPost:
Type: HttpApi
Properties:
ApiId: !Ref AdminApi
Path: /auctions
Method: options
CreateAuctionFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: ./src
Handler: handlers/create_auction.lambda_handler
Runtime: python3.9
Events:
ApiPost:
Type: HttpApi
Properties:
ApiId: !Ref AdminApi
Path: /auctions
Method: post
Environment:
Variables:
AUCTION_TABLE: !Sub "{{resolve:ssm:/applications/tikes/${Stage}/ddb/Auctions/TableName}}"
Policies:
- SSMParameterReadPolicy:
ParameterName: !Sub "applications/tikes/${Stage}/*"
- DynamoDBCrudPolicy:
TableName: !Sub "{{resolve:ssm:/applications/tikes/${Stage}/ddb/Auctions/TableName}}"
This template has a sibling template creating the DynamoDb table, I'm omitting it because that part is working fine. Here is the options lambda handler (adding a body had no effect on the headers):
def lambda_handler(event, context):
return {
'statusCode': 200,
}
And the success response I send from the POST handler:
def success_body(auction_id):
return {
'statusCode': 200,
'body': json.dumps({
'auction_id': auction_id
}),
}
Before adding the options lambda handler I was receiving a 204
response from the OPTIONS request without the allow-origin header, now that I added the handler I get a 200
as expected, however the header is still not there. With this configuration, sending a request with the same headers through PostMan will have the header on POST, but it will be missing with the OPTIONS request.
Things I have tried:
CorsConfiguration: true
- Hard-coding an origin
Things I've read:
- Fix CORS "Response to preflight..." header not present with AWS API gateway and amplify
- https://aws.amazon.com/premiumsupport/knowledge-center/no-access-control-allow-origin-error/
- https://www.serverless.com/blog/cors-api-gateway-survival-guide/
- https://aws.amazon.com/blogs/compute/configuring-cors-on-amazon-api-gateway-apis/
- https://aws.amazon.com/premiumsupport/knowledge-center/api-gateway-cors-errors/
- https://github.com/aws/aws-sam-cli/issues/2637
- https://forums.aws.amazon.com/thread.jspa?threadID=252972
- CORS impossible on AWS Lambda HTTP API Gateway Integration
- Any other aws cors question I could find.
The fact that the header is present in the POST request tells me that something is working. I just can't figure out why it works for one request but not the other.