Search code examples
amazon-web-servicescorsaws-api-gatewayhttp-status-code-303

Avoid CORS error on HTTP 303 redirect using AWS API Gateway and Lambda Proxy


I am running into a CORS error when returning a 303 redirection status on an API request. The API is hosted on AWS API Gateway, and uses an AWS Lambda integration with a proxy response. The API request is being made when the end user clicks a button on the site I am deploying.

Here is the CORS error:

Access to XMLHttpRequest at 'https://destination.com/' (redirected from 'https://my-api-endpoint.com') from origin 'http://source.com' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

I am returning the following proxy object from the Lambda function:

{
    "statusCode": 303,
    "headers": {
        "Access-Control-Allow-Origin": "*",
        "Access-Control-Allow-Headers": "*",
        "Access-Control-Allow-Methods": "*",
        "Access-Control-Allow-Credentials": True,
        "Location": "https://destination.com/",
    },
}

So it is not a matter of "Access-Control-Allow-Origin": "*" missing as a header in the request, which is really the only answer I have found through googling so far.

Furthermore, if I put the API endpoint into a browser it works as expected. From what I can tell the difference there is that when the endpoint is put directly into a browser, the sec-fetch-site header comes back as none, whereas when I click the button on my site the header comes back as cross-site, and that difference is causing the CORS error.

My use case here is a SaaS listing on AWS Marketplace, so when a user subscribes to the product I'll be listing, a POST request is sent to my API endpoint with a client token I need to ingest, and from there I need to route the end user to my landing page. To me the most natural way to handle this was an API endpoint that returns a 303 redirect, but naturally I will always run into a cross-origin issue since the source is the AWS Marketplace URL.

Does anyone know how to avoid this CORS error? If not, does anyone have another suggestion on how I should approach the issue?


Solution

  • Turns out the answer, like it so often does, was staring me right in the face. https://destination.com is a site I am hosting in an AWS S3 Bucket with a CloudFront Distribution sitting in front of it. The solution was to add a CORS configuration to the S3 Bucket, then create a custom cache policy in CloudFront. I then edited the default behavior of my CloudFront distribution to specify a cache policy (the one I just created), and an origin policy (CORS-S3Origin). Once I invalidated the distribution it worked like a charm. Thanks to @Evert for making me check what I thought I had already ruled out.