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 個月前

您尚未登入。 登入 去張貼答案。

一個好的回答可以清楚地回答問題並提供建設性的意見回饋,同時有助於提問者的專業成長。

回答問題指南