Cookie 已设置,但未发送到 Cloudfront

Cookies set, but not sent to Cloudfront

我正在尝试使用 signed cookies 访问 AWS Cloudfront 上的私有内容。

我的应用程序成功设置了云端所需的正确 cookie,并且每个 cookie 都有正确的值。作为参考,需要设置的三个cookie是:

我知道这些值是正确的,就像我抓取这些 cookie 并使用它们执行 curl 请求一样,它是成功的(为简洁起见,值替换为 ...):

curl -v -b "CloudFront-Signature=...; CloudFront-Policy==...; CloudFront-Key-Pair-Id==...;" http://mydistribution.cloudfront.net/myfile.jpg

故障

当我使用浏览器时,虽然我可以看到在我对服务器的原始请求中设置了 cookie http://localhost:3000/,但我对 Cloudfront url 的请求(例如,在我的图像标签中)没有通过在任何这些 cookie 上。这导致

<Error><Code>MissingKey</Code><Message>Missing Key-Pair-Id query parameter or cookie value</Message></Error>

知道为什么我的 cookie 没有被发送到云端吗?建议和支持表示赞赏:)

这是正常的:每个 cookie 都有一个关联的域,对于每个请求,浏览器只会发送与 URL 请求所针对的 cookie 相匹配的 cookie。

此外,您不能为任意域设置 cookie - 如果您的应用程序在 example.com 上,那么它可以为 example.com 和任何子域设置 cookie,但不能为其他域(例如 other-domain.com)

因此,如果浏览器以本地主机身份访问您的应用程序,则它无法设置发送到 foo.cloudfront.net 的 cookie。 cloudfront 中的签名 cookie 功能非常新,所以我不确定这里推荐的方法是什么,但是您可以配置 cloudfront 以将某些路径传递给您的应用程序(检查关于行为和起源的 cloudfront 文档)此时浏览器认为它正在与 cloudfront 对话,因此它可以让您设置 cookie,这些 cookie 将在后续请求中发送到您的 cloudfront 分发。

不过,您的应用确实需要从云端访问才能运行,因此我认为这在开发中不起作用。

或者使用 CNAME,以便您的云端分发和您的应用程序从同一个域提供服务。然而,这将意味着您不能使用默认的 cloudfront ssl 证书,除非 SNI 是可接受的,否则您需要支付额外费用才能使用您自己的证书。

解决方案是在 Cloudfront 上设置一个 CNAME 别名到 content.mydomain.com,然后将我的开发环境设置在 mydomain.com。当我将来转向生产时,这也需要设置。

现在他们共享相同的 TLD,cookie 可以免费传递到 cloudfront 并且它按预期工作。

感谢 Frederick Cheung 为我指明了正确的方向。

是的,这就是我们设置的方式,使用 CNAME 别名并在基域上设置 cookie,然后您就可以传递您的 cookie。

让我们更详细地说明一下,以防人们想知道下一步是什么,让我们使用上面的例子:-

  1. 您正在开发my.fancy.site.mydomain.com
  2. 您的 Cloudfront CNAME 别名是 content.mydomain.com
  3. 确保从您喜欢的应用程序
  4. 中将您的云端签名 cookie 设置为 .mydomain.com
  5. 从现在开始,您可以为 CF 传递 cookie。
  6. 一种快速测试您的 cookie 设置是否正确的方法,尝试获取您的资产 URL,然后将 url 直接放入浏览器。如果 cookie 设置正确,您将能够直接访问该文件。

如果您使用javascript获取cdn资产,请确保在您的JS代码中,您需要传递withCredentials选项,否则将无法使用。例如,如果您使用 jQuery,您将需要类似以下内容:-

$.ajax({
   url: a_cross_domain_url,
   xhrFields: {
       withCredentials: true
   }
});

如果请求成功,您应该从 CloudFront 收到 header 的响应 "Access-Control-blah-blah"。

希望搜索此答案的人对他们有所帮助。

aws 文档非常混乱和糟糕。因为它没有说如果您想要自定义策略,您将需要传递 CloundFront-Policy。

首先,您需要使 CNAME 正常工作。

其次,只要通过下面的cookie设置值,就可以了。你不需要在 Path 中指定最后的 url,只需输入 '/'

    $.cookie('CloudFront-Signature', '', {
                    path: '/', domain: '.mydomain.com'
});

    $.cookie('CloudFront-Key-Pair-Id', '', {
                    path: '/', domain: '.mydomain.com'
});

    $.cookie('CloudFront-Policy', '', {
                    path: '/', domain: '.mydomain.com'
});

对我有用。