1

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:

  1. CorsConfiguration: true
  2. Hard-coding an origin

Things I've read:

  1. Fix CORS "Response to preflight..." header not present with AWS API gateway and amplify
  2. https://aws.amazon.com/premiumsupport/knowledge-center/no-access-control-allow-origin-error/
  3. https://www.serverless.com/blog/cors-api-gateway-survival-guide/
  4. https://aws.amazon.com/blogs/compute/configuring-cors-on-amazon-api-gateway-apis/
  5. https://aws.amazon.com/premiumsupport/knowledge-center/api-gateway-cors-errors/
  6. https://github.com/aws/aws-sam-cli/issues/2637
  7. https://forums.aws.amazon.com/thread.jspa?threadID=252972
  8. CORS impossible on AWS Lambda HTTP API Gateway Integration
  9. 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.

gamda
  • 580
  • 6
  • 24

0 Answers0