Amazon s3 403使用fetch调用具有自定义域和签名cookie的Cloudfront S3端点时出错

Amazon s3 403使用fetch调用具有自定义域和签名cookie的Cloudfront S3端点时出错,amazon-s3,cookies,cors,fetch,amazon-cloudfront,Amazon S3,Cookies,Cors,Fetch,Amazon Cloudfront,我正在尝试通过Cloudfront使用签名cookie为S3 bucket创建一个私有端点。我已经成功地在Lambda中创建了一个签名cookie函数,它为我的根域添加了一个cookie 然而,当我为试图访问的S3文件调用Cloudfront端点时,我得到一个403错误。为了让事情变得更奇怪,我可以将URL复制粘贴到浏览器中,并可以访问该文件 我们将调用我的根域example.com。我的cookie域是.example.com,我的开发应用程序URL是test.app.example.com,

我正在尝试通过Cloudfront使用签名cookie为S3 bucket创建一个私有端点。我已经成功地在Lambda中创建了一个签名cookie函数,它为我的根域添加了一个cookie

然而,当我为试图访问的S3文件调用Cloudfront端点时,我得到一个403错误。为了让事情变得更奇怪,我可以将URL复制粘贴到浏览器中,并可以访问该文件

我们将调用我的根域
example.com
。我的cookie域是
.example.com
,我的开发应用程序URL是
test.app.example.com
,我的Cloudfront端点URL是
tilesets.example.com

在检查呼叫时,似乎没有发送cookies。这很奇怪,因为我的fetch调用有
凭据:“include”
,我正在调用cookie域的子域

配置如下:

S3:


我不确定我在这里会做错什么。特别奇怪的是,当我直接进入浏览器中的链接时,它就工作了,而当我获取链接时,它就不工作了,所以猜测这是CORS的问题

我一直在记录对Cloudfront的调用,正如您所看到的,在我的主应用程序中使用fetch时,没有发送cookie:

#Fields: date time x-edge-location sc-bytes c-ip cs-method cs(Host) cs-uri-stem sc-status cs(Referer) cs(User-Agent) cs-uri-query cs(Cookie) x-edge-result-type x-edge-request-id x-host-header cs-protocol cs-bytes time-taken x-forwarded-for ssl-protocol ssl-cipher x-edge-response-result-type cs-protocol-version fle-status fle-encrypted-fields

2019-09-13  22:38:40    IAD79-C3    369 <IP>    GET <CLOUDFRONT ID>.cloudfront.net  <PATH URL>/metadata.json    403 https://test.app.<ROOT DOMAIN>/ Mozilla/5.0%2520(Macintosh;%2520Intel%2520Mac%2520OS%2520X%252010_14_6)%2520AppleWebKit/537.36%2520(KHTML,%2520like%2520Gecko)%2520Chrome/76.0.3809.132%2520Safari/537.36   -   -   Error   5kPxZkH8n8dVO57quWHurLscLDyrOQ0L-M2e0q6X5MOe6K9Hr3wCwQ==    tilesets.<ROOT DOMAIN>  https   281 0.000   -   TLSv1.2 ECDHE-RSA-AES128-GCM-SHA256 Error   HTTP/2.0    -   -
#字段:日期时间x-edge-location sc字节c-ip cs方法cs(主机)cs uri系统sc状态cs(引用者)cs(用户代理)cs uri查询cs(Cookie)x-edge-result-type x-edge-request-id x-Host-header cs协议cs字节时间x-forwarded-for ssl协议ssl密码x-edge-response-result-type cs协议版本fle状态fle加密字段
2019-09-13 22:38:40 IAD79-C3 369 GET.cloudfront.net/metadata.json 403https://test.app./ Mozilla/5.0%2520(Macintosh;%2520Intel%2520Mac%2520OS%2520X%252010\u 14\u 6)%2520AppleWebKit/537.36%2520(KHTML,%2520like%2520Gecko)%2520Chrome/76.0.3809.132%2520Safari/537.36--错误5kPxZkH8n8dVO57quWHurLscLDyrOQ0L-M2e0q6X5MOe6K9Hr3wCwQ==瓷砖集。https 281 0.000-TLSv1.2 ECDHE-RSA-AES128-GCM-SHA256错误HTTP/2.0--
而当我直接在浏览器中访问URL时:

#Fields: date time x-edge-location sc-bytes c-ip cs-method cs(Host) cs-uri-stem sc-status cs(Referer) cs(User-Agent) cs-uri-query cs(Cookie) x-edge-result-type x-edge-request-id x-host-header cs-protocol cs-bytes time-taken x-forwarded-for ssl-protocol ssl-cipher x-edge-response-result-type cs-protocol-version fle-status fle-encrypted-fields

2019-09-13  22:32:38    IAD79-C1    250294  <IP>    GET <CLOUDFRONT ID>.cloudfront.net  <PATH URL>/metadata.json    200 -   Mozilla/5.0%2520(Macintosh;%2520Intel%2520Mac%2520OS%2520X%252010_14_6)%2520AppleWebKit/537.36%2520(KHTML,%2520like%2520Gecko)%2520Chrome/76.0.3809.132%2520Safari/537.36   -   CloudFront-Signature=<SIGNATURE>;%2520CloudFront-Key-Pair-Id=<KEY PAIR>;%2520CloudFront-Policy=<POLICY> Miss    gRkIRkKtVs3WIR-hI1fDSb_kTfwH_S2LsJhv9bmywxm_MhB7E7I8bw==    tilesets.<ROOT DOMAIN>  https   813 0.060   -   TLSv1.2 ECDHE-RSA-AES128-GCM-SHA256 Miss    HTTP/2.0    -   -
#字段:日期时间x-edge-location sc字节c-ip cs方法cs(主机)cs uri系统sc状态cs(引用者)cs(用户代理)cs uri查询cs(Cookie)x-edge-result-type x-edge-request-id x-Host-header cs协议cs字节时间x-forwarded-for ssl协议ssl密码x-edge-response-result-type cs协议版本fle状态fle加密字段
2019-09-13 22:32:38 IAD79-C1 250294 GET.cloudfront.net/metadata.json 200-Mozilla/5.0%25202520CloudFront密钥对Id=;%2520CloudFront Policy=Miss grkirktTvs3wir-hI1fDSb_kTfwH_S2LsJhv9bmywxm_MhB7E7I8bw==瓷砖集。https 813 0.060-TLSv1.2 ECDHE-RSA-AES128-GCM-SHA256 Miss HTTP/2.0--

有什么想法吗?

您已经正确地诊断出问题在于您的cookies没有被发送

跨源请求将不包括具有
凭据:“include”
的Cookie,除非源服务器在其响应头中还包括权限:

Access-Control-Allow-Credentials: true
让S3实现这一点的方法并不明显,但我在中发现了一个线索之后偶然发现了这个解决方案

修改bucket的CORS配置以删除此选项:

*
…并添加以下内容,具体列出您希望允许访问bucket的源(根据您的描述,这将是父域):

https://example.com
(如果您需要http,则需要单独列出,并且需要列出您需要允许使用CORS访问bucket的每个域。)

这将更改S3的行为,使其包含
访问控制允许凭据:true
。它似乎没有明确的文档记录

在不了解其含义的情况下,不要使用以下替代方法,即使它也会起作用

https://*
这也会导致访问控制允许凭据:true,因此它“工作”——但它允许从任何地方跨源,这可能是您不希望的。尽管如此,请记住CORS只不过是一种权限机制,只适用于行为良好的非恶意web浏览器——因此将允许的源设置设置为只允许正确的域很重要,但它不会神奇地保护您的内容,防止来自其他地方的未授权访问。我想你已经意识到了这一点,但记住这一点很重要


在这些更改之后,您需要清除浏览器缓存并使CloudFront缓存无效,然后重新测试。正确设置CORS标题后,浏览器应发送cookie,问题应得到解决。

您已正确诊断出问题在于cookie未被发送

跨源请求将不包括具有
凭据:“include”
的Cookie,除非源服务器在其响应头中还包括权限:

Access-Control-Allow-Credentials: true
让S3实现这一点的方法并不明显,但我在中发现了一个线索之后偶然发现了这个解决方案

修改bucket的CORS配置以删除此选项:

*
…并添加以下内容,具体列出您希望允许访问bucket的源(根据您的描述,这将是父域):

https://example.com
(如果您需要http,则需要单独列出,并且需要列出您需要允许使用CORS访问bucket的每个域。)

这将更改S3的行为,使其包含
访问控制允许凭据:true
。它似乎没有明确的文档记录

不要使用以下命令