HTTP no-cache access to S3 versioned objects

0

I'm surprised I haven't seen this issue online.

Currently I have an S3 bucket that is served through Cloudfront on a custom domain. e.g. An S3 bucket object is retrievable publicly via https://cdn.mywebsite.com/picture.jpeg.

The cloudfront distribution connects with the origin (S3) through an OAC, and the policy was applied to the bucket correctly.

I am able to retrieve all objects today, however there is some invisible caching and I'm unsure how to get around it.

For example, I can reach and retrieve https://cdn.mywebsite.com/picture.jpeg without issues. Then, when I go to retrieve https://cdn.mywebsite.com/picture.jpeg?versionId=...., I get the same response as the prior call. It's cached.

How can I retrieve https://cdn.mywebsite.com/picture.jpeg?versionId=.... without caching?

Here's what I've tried:

  • Under my origin behavior, I have used the CachingDisabled policy under "Cache key and origin requests". This does indeed disable caching, but that policy doesn't forward query string arguments, so picture.jpeg and picture.jpeg?versionId=... are retrieved equivalently.
  • I have tried creating an identical cache policy as CachingDisabled, with Query strings - All set for the cache key settings. As a result, I get a 403 error.

My interpretation is that when a request is sent via cdn.myexample.com/picture.jpeg?versionId=..., that version query string is stripped off before going to the S3 bucket. Hence, it doesn't cache picture.jpeg, but it's not retrieving the right image anymore.

已提问 1 个月前261 查看次数
1 回答
1
已接受的回答

Hey all, I fixed it. Since this had me pulling my hair out, here was my solution:

  • On the Cloudfront distribution, Edit the Behavior for the S3 Cloudfront bucket.
  • Find Cache key and origin requests and edit this so Headers includes the Origin, and set Query strings to All.

Finally, this is an important step. On the S3 bucket, you must give access to the Cloudfront distribution to get version tagging. I haven't narrowed down exactly which action solved it for me, but here's what worked:

{
    "Version": "2008-10-17",
    "Id": "PolicyForCloudFrontPrivateContent",
    "Statement": [
        {
            "Sid": "AllowCloudFrontServicePrincipal",
            "Effect": "Allow",
            "Principal": {
                "Service": "cloudfront.amazonaws.com"
            },
            "Action": [
                "s3:GetObject",
                "s3:GetObjectVersionTagging",
                "s3:GetObjectVersion"
            ],
            "Resource": "arn:aws:s3:::.... my bucket",
            "Condition": {
                "StringEquals": {
                    "AWS:SourceArn": "arn:aws:cloudfront::..... my distribution"
                }
            }
        },
        {
            "Sid": "Statement1",
            "Effect": "Allow",
            "Principal": {
                "Service": "cloudfront.amazonaws.com"
            },
            "Action": [
                "s3:ListBucket",
                "s3:ListBucketVersions"
            ],
            "Resource": "arn:aws:s3:::.... my bucket",
            "Condition": {
                "StringEquals": {
                    "AWS:SourceArn": "arn:aws:cloudfront::..... my distribution"
                }
            }
        }
    ]
}
已回答 1 个月前
profile picture
专家
已审核 1 个月前
profile picture
专家
已审核 1 个月前

您未登录。 登录 发布回答。

一个好的回答可以清楚地解答问题和提供建设性反馈,并能促进提问者的职业发展。

回答问题的准则