'Access-Control-Allow-Origin' header value not equal to the supplied origin, POST method

0

I get the following message in the Chrome dev tools console when submitting a contact form on the /about.html section my portfolio web site:

Access to XMLHttpRequest at 'https://123abc.execute-api.us-east-1.amazonaws.com/prod/contact' from origin 'https://myportfoliositeabc123.net' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: The 'Access-Control-Allow-Origin' header has a value 'https://myportfoliositeabc123.net/' that is not equal to the supplied origin.

I don't know how to troubleshoot this properly, any help is appreciated. Also where is the 'Access-Control-Allow-Origin' header has a value set? It is in the S3 bucket permissions > CORS, correct? Essentially, this is happening, and I'm not sure how to fix it in AWS (https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS/Errors/CORSAllowOriginNotMatchingOrigin)

Here is a description of the AWS stack:

  1. Context, I am using an S3 bucket as static website using CloudFront and Route 53, this stuff works fine, has for years. When I added the form, I did the following to allow the HTTP POST request:

  2. Cloudfront, On the site's distribution I added a behavior with all settings default except:

  • Path pattern: /contact (I am using this bc this is the API Gateway resource path ending)
  • Origin and origin groups: S3-Website-myportfoliositeabc123.net.s3-website... (Selected correct origin)
  • Viewer protocol policy: HTTP and HTTPS
  • Allowed HTTP methods: GET, HEAD, OPTIONS, PUT, POST, PATCH, DELETE

Cache HTTP methods GET and HEAD methods are cached by default: Checked OPTIONS box

  • Origin request policy - optional: CORS-S3Origin
  • Response headers policy - optional: CORS-With-Preflight
  1. API Gateway, Created a REST API with all default settings except:
  • Created a resource: /contact
  • Created a method: POST
  • For /contact, Resource Actions > Enable CORS:
  • Methods: OPTIONS and POST both checked
  • Access-Control-Allow-Origin: 'https://myportfoliositeabc123.net' (no ending slash)
  • Clicked "Enable CORS and Replace existing headers"
  • Results are all checked green: ✔ Add Access-Control-Allow-Headers, Access-Control-Allow-Methods, Access-Control-Allow-Origin Method Response Headers to OPTIONS method ✔ Add Access-Control-Allow-Headers, Access-Control-Allow-Methods, Access-Control-Allow-Origin Integration Response Header Mappings to OPTIONS method ✔ Add Access-Control-Allow-Origin Method Response Header to POST method ✔ Add Access-Control-Allow-Origin Integration Response Header Mapping to POST method
  • Created a stage called "prod", ensured it had the /contact resource, and deployed.
  • At the /contact - POST - Method Execution, The test works as expected (triggers Lambda func that uses SES to send email, which I do actually receive). The only thing I feel unsure about with API Gateway is after I enable the CORS, I can't seem to find a place where that setting has been saved, and if I click again on enable CORS, it is back to the default form ( with Access-Control-Allow-Origin: '')*
  1. Amazon SES, set up 2 verified identities for sending/receiving emails via lamda.

  2. Lamda, set up a basic javascript function with default settings, the REST API is listed as a trigger, and does actually work as previously mentioned. The function code is:

    var AWS = require('aws-sdk');
    var ses = new AWS.SES({ region: "us-east-1" });
    var RECEIVER = 'myemail@email.com';
    var SENDER = 'me@myportfoliositeabc123.net';
    var response = {
        "statusCode": 200,
        "headers": {
            "Content-Type": "application/json",
            "Access-Control-Allow-Origin": "*"
        },
        "isBase64Encoded": false,
        "body": "{ \"result\": \"Success\"\n}"
    }
    exports.handler = async function (event, context) {
        console.log('Received event:', event);
        var params = {
            Destination: {
                ToAddresses: [
                    RECEIVER
                ]
            },
            Message: {
                Body: {
                    Text: {
                        Data: 'first name: ' + event.fname + 'last name: ' + event.lname + '\nemail: ' + event.email + '\nmessage: ' + event.message,
                        Charset: 'UTF-8'
                    }
                },
                Subject: {
                    Data: 'Website Query Form: ' + event.name,
                    Charset: 'UTF-8'
                }
            },
            Source: SENDER
        };
        return ses.sendEmail(params).promise();
    };

    The only thing i can think of here is to maybe update the response to have "headers": {"Access-Control-Allow-Origin": "https://myportfoliositeabc123.net"}

    S3 bucket that holds the site contents, in permissions > CORS, I have the following JSON to allow a post of the contact form (notice no slash):

    [
        {
            "AllowedHeaders": [
                "*"
            ],
            "AllowedMethods": [
                "POST"
            ],
            "AllowedOrigins": [
                "https://myportfoliositeabc123.net"
            ],
            "ExposeHeaders": []
        }
    ]
  3. Permissions/Roles, Established Roles and permissions per

  • AWS guide: create dynamic contact forms for s3 static websites using aws lambda amazon api gateway and amazon ses
  • video titled: "Webinar: Dynamic Contact Forms for S3 Static Websites Using AWS Lambda, API Gateway & Amazon SES" Console logged CORS errors POST Request Method OPTIONS
2 Answers
-1

Hello,

I am trying to understand your problem:

  1. You are using S3 + CloudFront + Route53 for static website hosting https://myportfoliositeabc123.net
  2. you have a api gateway https://123abc.execute-api.us-east-1.amazonaws.com/prod/contact which you calling from your website javascript code and you getting CORS error. You have also enable CROS on your api gateway for this "POST" /contact method.

Please try following to see if it resolve your issue

  1. Open again API Gateway and select /contact resource and re configure CORS, fill Access-Control-Allow-Origin as https://myportfoliositeabc123.net and save the changes
  2. You should see OPTION method added under /contact resource.
  3. Re-deploy your api under prod stage

Test your website client code, check following

  1. Ensure you client code is making POST method call to https://123abc.execute-api.us-east-1.amazonaws.com/prod/contact
  2. under dev console you should see preflight OPTION method call happening
  3. eventually your code should get response.

I would also suggest to clean all configuration which you did in cloudfront which you listed in point 2. They are not required to have any kind of behaviour configuration for api gateway.

answered a year ago
  • Thanks for responding.

    In response to your suggestion to try to resolve the issue: Regarding #1, I had already done that. I should have mentioned that when either 1. when enabling CORS in the API Gateway or 2. when creating the POST method, the OPTIONS method appeared (As you mentioned happens in your #2). I have retried enabling CORS and redeploying a few times (as you mentioned in #3), since there is no state of CORS settings able to be viewed for a resource.

    In response to testing the client code: Regarding 1) I have verified the client code is making the POST method call to the correct API url.
    Regarding 2) I do see the preflight OPTION method call in Chrome's dev tools network section. Regarding 3) It does NOT get a response, and in the console thats where there is logged the CORS error.

    While this did not fix my problem, this prompted me to dig around the dev tools a bit more. I now realize there really is no mismatch (i thought it could be related to the trailing slash, but I see the dev tools "issues" area it lists "initiator context" and "Allowed Origin" as the exact same address. I will add images to the initial problem showing what the dev tools is displaying.

    The reason I update the Cloudfront behavior is based on this artice, which is the first issue I overcame (https://aws.amazon.com/premiumsupport/knowledge-center/no-access-control-allow-origin-error/). I'll leave it be for now.

    I've updated the content of the question.

  • Ok are you providing allowed header? as you have seen doing CORS setting enabling on API Gateway console, and same you can also see in your screenshot OPTION method response header. If you are not using all headers, then just set those which you need.

-1

The problem was that the response in the lambda function had "Access-Control-Allow-Origin" set to "*".

This should have been set to the exact origin, so if the origin is 'https://myportfoliositeabc123.net', then the response in the lamda function should have "Access-Control-Allow-Origin" set to 'https://myportfoliositeabc123.net' as shown below:

var response = {
    "statusCode": 200,
    "headers": {
        "Content-Type": "application/json",
        "Access-Control-Allow-Origin": "https://myportfoliositeabc123.net"
    },
    "isBase64Encoded": false,
    "body": "{ \"result\": \"Success\"\n}"
}```
lrmcc
answered a year ago
  • change * to https://myportfoliositeabc123.net does not matter. as * means allow all domains.. it kind of wildcard allow, hence you need to see what change made it working, if you really want to know.

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.

Guidelines for Answering Questions