Amazon Cloudfront: частный контент, но максимизирует кеширование локального браузера

Для доставки изображений JPEG в моем веб-приложении я рассматриваю возможность использования Amazon S3 (или Amazon Cloudfront если он окажется лучшим вариантом), но имеют два, возможно, противоположных, Требования:

  • Изображения являются частным контентом; Я хочу использовать подписанные URL-адреса с короткими сроками истечения срока действия.
  • Изображения большие; Я хочу, чтобы они были кэшированы в течение длительного времени браузером пользователей.

Подход, о котором я думаю:

  • Пользовательские запросы www.myserver.com/the_image
  • Логика на моем сервере определяет, что пользователю разрешено просматривать изображение. Если они разрешены...
  • Перенаправить браузер (is HTTP 307 best ?) на подписанный URL Cloudfront
  • Подписанный URL-адрес Cloudfront истекает через 60 секунд, но его ответ включает "Cache-Control max-age=31536000, private"

Проблема, которую я вижу, заключается в том, что в следующий раз, когда страница загружается, браузер будет искать www.myserver.com/the_image, но его кеш будет для подписанного URL Cloudfront. Мой сервер будет возвращать другой подписанный URL Cloudfront во второй раз из-за очень коротких срок действия, поэтому браузер не будет знать, что он может использовать свой кеш.

Есть ли способ обойти это без моего прокси-сервера веб-сервера изображения из Cloudfront (что, очевидно, отрицает все преимущества использования Cloudfront)?

Интересно, может ли быть что-то, что я мог бы сделать с etag и HTTP 304, но не могу присоединиться к точкам...

Ответ 1

Итак, у вас есть частные образы, которые вы хотите использовать через Amazon Cloudfront через подписанные URL-адреса с очень коротким сроком действия. Однако, хотя доступ к определенному URL-адресу может быть ограниченным временем, желательно, чтобы клиент обслуживал изображение из кеша при последующих запросах даже после истечения срока действия URL-адреса.

Независимо от того, как клиент достигает URL-адреса облачного (напрямую или с помощью перенаправления сервера), клиентский кэш изображения будет связан только с конкретным URL-адресом, который использовался для запроса изображения (а не другого URL-адреса).

Например, предположим, что ваш подписанный URL-адрес следующий (временная метка истечения срока действия сокращена, например, для целей):

http://[domain].cloudfront.net/image.jpg?Expires=1000&Signature=[Signature]

Если вы хотите, чтобы клиент использовал кеширование, вы должны отправить его на тот же URL-адрес. Например, вы не можете направить клиента на следующий URL-адрес и ожидать, что клиент будет использовать кешированный ответ с первого URL-адреса:

http://[domain].cloudfront.net/image.jpg?Expires=5000&Signature=[Signature]

В настоящее время нет механизмов управления кэшем, в том числе ETag, Vary и т.д. Характер кэширования клиентов в Интернете заключается в том, что ресурс в кеше связан с URL-адресом, а целью других механизмов является чтобы помочь клиенту определить, когда его кешированная версия ресурса, идентифицированного конкретным URL, еще свежая.

Таким образом, вы застряли в ситуации, когда, чтобы извлечь выгоду из кэшированного ответа, вы должны отправить клиент на тот же URL-адрес, что и первый запрос. Существуют потенциальные возможности для этого (файлы cookie, локальное хранилище, серверные скрипты и т.д.), И предположим, что вы его внедрили.

Вам следует подумать, что кеширование - это всего лишь предложение, и даже тогда это не гарантия. Если вы ожидаете, что клиент будет кэшировать изображение и подаст ему исходный url, чтобы извлечь выгоду из этого кэширования, вы рискуете пропустить кеш. В случае промаха в кеше после истечения срока действия URL-адреса исходный URL-адрес больше недействителен. Затем клиент не может отображать изображение (из кеша или из предоставленного URL-адреса).

Поведение, которое вы ищете, просто не может быть обеспечено обычным кэшированием, когда время истечения срока действия в URL-адресе.

Поскольку желаемое поведение не может быть достигнуто, вы можете рассмотреть свои следующие лучшие варианты, каждый из которых потребует отказа от одного аспекта вашего требования. В следующем порядке я бы их рассмотрел:

  • Если вы откажетесь от коротких сроков истечения срока действия, вы можете использовать более длительные сроки истечения срока действия и вращать URL-адреса. Например, вы можете установить срок действия URL-адреса до полуночи, а затем использовать тот же URL-адрес для всех запросов в этот день. Ваш клиент получит выгоду от кэширования на день, что, вероятно, лучше, чем вообще. Очевидным недостатком является то, что ваши URL-адреса действительны дольше.

  • Если вы отказались от доставки контента, вы можете обслуживать изображения с сервера, который проверяет доступ с каждым запросом. Клиенты смогут кэшировать ресурс столько, сколько захотите, что может быть лучше, чем доставка контента в зависимости от частоты просмотров кеша. Вариант этого заключается в том, чтобы торговать Amazon CloudFront для другого провайдера, поскольку могут существовать другие сети доставки контента, которые поддерживают это поведение (хотя я и не знаю). Потеря сети доставки контента может быть недостатком или может не иметь большого значения в зависимости от ваших конкретных посетителей.

  • Если вы откажетесь от простой статического HTTP-запроса, вы можете использовать скрипты на стороне клиента, чтобы определить запросы (запросы), которые должны быть сделаны. Например, в javascript вы можете попытаться извлечь ресурс с использованием исходного URL-адреса (чтобы извлечь выгоду из кеширования), и если он не работает (из-за промаха в кеше и истечения срока действия), запросите новый URL-адрес для использования ресурса. Вариант этого заключается в использовании некоторого механизма кэширования, отличного от кеша браузера, например локального хранилища. Недостатком здесь является повышенная сложность и уязвимость для предварительной выборки браузера.

Ответ 2

Сохраните список пользователей + изображение + срок действия → облачные ссылки. Если у пользователя есть связанная с ним несрочная линия облачной связи, используйте ее для изображения и не создавайте новую.

Ответ 3

Кажется, вы уже решили проблему. Вы сказали, что ваш сервер отправляет перенаправление http 307 на URL-адрес облачного URL (подписанный URL-адрес), поэтому браузер кэширует только URL облачной точки, а не ваш URL-адрес (www.myserver.com/the_image). Таким образом, сценарий выглядит следующим образом:  Клиент 1 проверяет, что www.myserver.com/the_image → перенаправляется на URL CloudFront → содержимое кэшируется Теперь URL-адрес CloudFront истекает.

Клиент 1 снова проверяет. www.myserver.com/the_image → перенаправляется на тот же URL-адрес CloudFront → извлекает содержимое из кеша, не возвращая содержимое облачного интерфейса.

Проверки клиента 2 www.myserver.com/the_image → перенаправляется на URL-адрес CloudFront, который отрицает его доступ, потому что подпись истекла.