尽管在使用 Lambda、API 网关和 Cloudfront 时在 Lambda 响应中指定了 'Access-Control-Allow-Origin',但仍出现 CORS 错误

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

我有一个已部署的 Web 应用程序,它是使用托管在 S3 上的 React 和 Redux 前端构建的,以及几个托管在 AWS Lambda 上并通过 API 网关公开的后端 micro-services无服务器。该站点还通过 CloudFront CDN 分发。

micro-services 与多个外部服务交互,但我最关心的是 get-products 服务,它查询 Stripe 产品数据库和 returns 产品到我的 React 应用程序从那里开始。

该网站一直运行良好,直到昨天我对前端部署了一些新的(基本上是装饰性的)更改,并向 Stripe 数据库添加了更多的 SKU。自从添加这些更改后,我开始遇到 CORS 错误,而之前 none.

最初我收到以下错误:

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.

尽管我的 Lambda 响应包括以下 headers:

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

此时我将我的 Lambdas 响应 headers 更新为以下内容:

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

错误基本上一直存在,除了在一个随机页面加载时,我收到一条错误消息,指出 Origin https://www.superfunwebsite.com 和 'Access-Control-Allow-Origin' https://www.superfunwebsite.com/ 不匹配。

我已经将 Lambda 响应 headers 更改为:

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

这似乎解决了第二个异常错误。

但是,即使我使用像 Insomnia 这样的 HTTP 客户端进行测试,错误一仍然存在。我在回复中得到以下内容。

// 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==

根据上面的 Insomnia 输出,我的问题似乎与 CloudFront 在某种程度上有关,尽管我不明白具体是如何发生的。 This other S/O post 似乎表明在 CloudFront 行为部分应该有适合我的选项,允许我将响应列入白名单 headers,但是我在控制台中看不到这些选项,我已经看到建议这是因为原点在 S3 上。

我的问题很简单,是否有人知道我可以如何解决这个问题,或者是否还有其他我认为不应该关注的问题?

在这里,您必须在云端分布的行为部分将相应的 CORS headers 列入白名单。

  1. 从 Amazon CloudFront 控制台打开您的分配
  2. 选择“行为”视图。
  3. 选择创建行为,或选择现有行为,然后选择编辑。
  4. 对于选项 Cache Based on Selected Request Headers,选择白名单。
  5. 在白名单 Headers 下,从左侧菜单中选择 headers(Access-Control-Request-HeadersAccess-Control-request-methodsOrigin),然后选择添加。
  6. 选择是,编辑。

以上设置应该适合您(因为它主要针对 GETHEAD)但如果不适合,请使用下面的文章启用 OPTIONS 方法。 请查看以下来自 aws 的文章:

no-access-control-allow-origin-error

Custom CORS Cloudfront

enhanced-cloudfront-customization

此问题现已解决。最后,这实际上不是 CORS 问题,而是暂存问题。我的查询失败了,因为我正在查询一个不存在的端点阶段。

似乎在我使用 CloudFront 和 API 网关的设置中,当查询一个不存在的端点时,我返回了一个没有 CORS 403 的响应 headers .

browser/CloudFront(不确定是哪个)随后发现缺少 CORS headers 并抛出一个错误作为回应。

在我的例子中,只需从开发阶段更改我的端点(在与实时阶段关联的关联 AWS 账户上不存在):

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

到现场:

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

立即解决了问题。