Кеширование браузера shrine s3 приватные вложения

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

У меня есть следующий инициализатор храма:

s3_options = {
  access_key_id: ENV['AWS_ACCESS_KEY_ID'],
  secret_access_key: ENV['AWS_SECRET_ACCESS_KEY'],
  region: ENV['AWS_REGION'],
  bucket: ENV['S3_BUCKET_NAME']
}

Shrine.storages = {
  cache: Shrine::Storage::FileSystem.new('tmp', prefix: 'uploads/cache'),
  store: Shrine::Storage::S3.new(**s3_options)
}

Shrine.plugin :activerecord
Shrine.plugin :logging
Shrine.plugin :determine_mime_type
Shrine.plugin :cached_attachment_data
Shrine.plugin :restore_cached_data
Shrine.plugin :delete_promoted
Shrine.plugin :delete_raw
Shrine.plugin :remove_invalid

И следующий загрузчик:

class AvatarUploader < Shrine
  plugin :pretty_location
  plugin :processing
  plugin :upload_options, store: {
    acl: 'private',
    cache_control: "max-age=604800",
  }
end

CacheControl правильно установлен на 1 неделю для объекта s3, и то же самое видно в ответе. Я заметил, что при каждом запросе подписанный URL-адрес отличается в отношении хэша X-Amz-Signature, что, скорее всего, приводит к отсутствию кэша (Etag одинаков для каждого запроса). Я предполагаю, что это причина того, что это не работает, но я понятия не имею, как сделать X-Amz-Signature такой же, пока объект не просрочен.

1 ответ

Решение

Ruby S3 SDK будет генерировать новую подпись каждый раз, когда вы создаете подписанный URL, это сделано специально.

Вы должны либо

а) придерживаться публичных, не подписанных запросов

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

Нечто подобное может сработать

def url
  Rails.cache.fetch("url", self, expires_in: 6.days) do
    super(public: false, expires_in: 1.week)
  end
end
Другие вопросы по тегам