Cookie已设置,但未发送至Cloudfront

时间:2015-04-25 12:59:35

标签: ruby-on-rails cookies amazon-web-services amazon-cloudfront

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

  • 在Puma服务器上开发的Rails 4.2.1应用程序 - http://localhost:3000
  • 使用最新的Chrome(并且可以在Firefox和Safari中重现)

我的应用成功设置了cloudfront所需的正确Cookie,每个Cookie都具有正确的值。作为参考,需要设置的三个cookie是:

  • CloudFront的-政策
  • CloudFront的签名
  • CloudFront的-密钥对-ID

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

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

故障

当我使用浏览器时,虽然我可以看到cookie已经在我对服务器http://localhost:3000/的原始请求中设置,但我对Cloudfront网址的请求(例如,在我的图片标记中)不会传递任何这些饼干。这导致

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

为什么我的cookie没有被发送到Cloudfront的任何想法?建议和支持表示赞赏:)

4 个答案:

答案 0 :(得分:4)

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

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

因此,如果您的应用程序被浏览器作为localhost访问,那么它就无法设置发送到foo.cloudfront.net的cookie。在cloudfront中签名的cookie功能非常新,所以我不确定推荐的方法是什么,但是您可以配置cloudfront将某些路径传递到您的应用程序(检查有关行为和来源的cloudfront文档)浏览器认为它正在与cloudfront通信,因此它允许您设置将在后续请求中发送到您的Cloudfront分发的cookie。

您的应用确实需要从云端访问才能实现此功能,因此我认为这不会在开发中发挥作用。

或者使用CNAME,以便从同一个域提供您的Cloudfront分发和您的应用。但这意味着您无法使用默认的cloudfront ssl证书,除非SNI可以接受,否则您需要支付额外费用才能使用自己的证书。

答案 1 :(得分:1)

解决此问题的方法是在Cloudfront上为 content.mydomain.com 设置CNAME别名,然后将我的开发环境设置为 mydomain.com 。当我将来转向生产时,也需要设置它。

现在他们共享相同的TLD,cookie可以自由传递到Cloudfront,并且可以按预期工作。

感谢Frederick Cheung指出我正确的方向。

答案 2 :(得分:0)

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

如果人们想知道下一步是什么,让我们更多细节,让我们使用上面的例子: -

  1. 您正在开发 my.fancy.site.mydomain.com
  2. 您的Cloudfront CNAME别名为 content.mydomain.com
  3. 确保将您的Cloudfront签名Cookie设置为 .mydomain.com 来自您的精美应用
  4. 从现在开始,您可以传递CF的cookie。
  5. 测试您的Cookie是否设置正确的一种快速方法,尝试获取您的资源网址,并将网址直接放入浏览器中。如果cookie设置正确,您将能够直接访问该文件。
  6. 如果您使用javascript获取cdn资产,请确保在JS代码中,您需要传递withCredentials选项,否则它将无效。例如,如果您使用的是jQuery,则需要以下内容: -

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

    如果请求成功,您应该从CloudFront获取带有“Access-Control-blah-blah”的响应头。

    希望如果他们搜索这个答案,它可以帮助人们。

答案 3 :(得分:0)

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

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

其次,只需在下面通过cookie设置值,它就可以了。您无需在Path中指定最终网址,只需输入“/”

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

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

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

它对我有用。