简体   繁体   中英

CORS error despite 'Access-Control-Allow-Origin' specified in Lambda response when using Lambda, API Gateway and Cloudfront

I have a deployed web app, it's built with a React & Redux frontend hosted on S3, and a several backend micro-services hosted on AWS Lambda and exposed over API Gateway that were deployed with Serverless. The site is also distributed via a CloudFront CDN.

The micro-services interact with several external services but the primary one I am concerned with is the get-products service which queries the Stripe product database and returns the products to my React app from there.

The site has been working fine until yesterday when I deployed some new (basically cosmetic) changes to front end, and added some more SKUs to the Stripe database. Since adding these changes I have started to experience CORS errors where previously there were none.

Initially I got the following error:

Access to XMLHttpRequest at 'https://XXXXXXXXXX.execute-api.eu-west-1.amazonaws.com/dev/products' from origin 'https://www.superfunwebsite.com' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

This was despite my Lambda response including the following headers:

'Access-Control-Allow-Origin': '*',

At this point I updated my Lambdas response headers to the following:

'Access-Control-Allow-Origin': 'https://www.superfunwebsite.com/',
'Access-Control-Allow-Credentials': true

The error has largely persisted, except for on one random page load where instead I got an error stating that the Origin https://www.superfunwebsite.com and 'Access-Control-Allow-Origin' https://www.superfunwebsite.com/ didn't match.

I've since changed the Lambda response headers to this:

'Access-Control-Allow-Origin': 'https://www.superfunwebsite.com',
'Access-Control-Allow-Credentials': true

Which seems as though it may have solved that anomalous second error.

However, error one persists even when I am testing using a HTTP client like Insomnia. I get the following in the response.

// status code
403

// response
{
  "message": "Forbidden"
}

// headers
Content-Type: application/json
Content-Length: 23
Connection: keep-alive
Date: Tue, 18 Sep 2018 13:22:41 GMT
x-amzn-RequestId: eb691541-bb45-11e8-82ff-6d1b542dffb9
x-amzn-ErrorType: ForbiddenException
x-amz-apigw-id: NaxVLGJgjoEF5Fg=
X-Cache: Error from cloudfront
Via: 1.1 08037e15a3c6f503f39825efeb7f0210.cloudfront.net (CloudFront)
X-Amz-Cf-Id: cbNtb4xKWc48VPFon-Cl9y27KmXRVLIN5SWuYwNWlWsTXeaAXx3z-Q==

Based on the above Insomnia output it seems that my issue is somehow related to CloudFront although I don't understand exactly how. This other S/O post seems to indicate that there should be options for me in the CloudFront behaviours section that would allow me to whitelist headers for the response, however these options are not visible to me in the console, I've seen suggestions this is because the origin is on S3.

My question is simply if anyone knows how I can fix this issue or if there is something else I've not considered that I should be looking at?

Here you have to Whitelist the respective CORS headers in the behaviour section of the cloudfront distribution.

  1. Open your distribution from the Amazon CloudFront console
  2. Choose the Behaviors view.
  3. Choose Create Behavior, or choose an existing behavior and then choose Edit.
  4. For option Cache Based on Selected Request Headers , choose Whitelist.
  5. Under Whitelist Headers, choose headers ( Access-Control-Request-Headers and Access-Control-request-methods , Origin ) from the menu on the left, and then choose Add.
  6. Choose Yes, Edit.

在此处输入图片说明

The above settings should work for you (as its mainly for GET and HEAD ) but if it doesn't, enable OPTIONS method as well using below article. Please check the below article from aws:

no-access-control-allow-origin-error

Custom CORS Cloudfront

enhanced-cloudfront-customization

This issue has now been solved. In the end it was not in fact a CORS issue but a staging one. My query was failing because I was querying an endpoint stage that did not exist.

It appears that in the set up I had using CloudFront and API Gateway, when querying an endpoint that didn't exist I was returned a 403 response without CORS headers.

The browser/CloudFront (not sure which) then identified the absence of CORS headers and threw an error in response to that.

In my case simply changing my endpoint from the dev stage (which did not exist on the associated AWS account associated with the live stage):

https://XXXXXXXXXX.execute-api.eu-west-1.amazonaws.com/dev/products

To the live stage:

https://XXXXXXXXXX.execute-api.eu-west-1.amazonaws.com/live/products

Resolved the issue immediately.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM