После некоторого поиска и борьбы с этим в течение длительного времени я нашел страницу, в которой говорится, что CarrierWave не поддерживает подписанные URL-адреса CloudFront. Подписанные URL-адреса CloudFront отличаются от подписанных URL-адресов S3, что вызвало у меня некоторую путаницу. Как только я понял это, было намного легче узнать, что делать.
При настройке CarrierWave с config.fog_public = false
то он автоматически начнет подписывать S3 URLs, но он не может быть сконфигурирован для работы с Fog
и CloudFront частного содержания в версии CarrierWave я использую (1.0.0)
. Я даже попытался использовать драгоценный камень carrierwave-aws
, и это тоже не помогло.
Так что же случится, что CarrierWave подпишет URL и хост будет выглядеть примерно так:
https://my_bucket_name.s3-us-west-2.amazonaws.com/uploads/...?signature...
Это указывает непосредственно на ведро S3, но мне нужно, чтобы она указывала на CloudFront. Я нужен хозяин, чтобы выглядеть следующим образом:
https://s3.cloudfront_domain_name.com/uploads/...
А что произойдет, если я установить config.asset_host
равного моей CloudFront место, я бы получить это (с двойной косой чертой перед «загрузкой»):
https://s3.cloudfront_domain_name.com//uploads/...
Это тоже показало, что CarrierWave еще не предназначен для использования с CloudFront. Надеюсь, они улучшат его. Это была моя работа. Это уродливо, но он работал, чтобы сделать то, что мне нужно, без необходимости изменять CarrierWave, так как я надеюсь, что CarrierWave в какой-то момент добавит поддержку CloudFront.
- Сначала я сделал регулярное выражение поиска/замены на моих URL и удалил часть хоста S3 и положить на моей CloudFront узловой части.
cf_url = s3_url.gsub("my_bucket_name.s3-us-west-2.amazonaws.com", "s3.cloudfront_domain_name.com")
- Далее я еще регулярное выражение поиска/замены для удаления S3 подписали URL в конце строки:
non_signed_cf_url = cf_url.gsub(/\?.+/, '')
Это происходит потому, что подпись будет неправильно, потому что он был с помощью API для S3, а не для CloudFront для подписывая URL.
- Теперь я заново подписывать URL сам, используя
cloudfront-signer
перл: signed_cf_url = Aws::CF::Signer.sign_url(non_signed_cf_url, :expires => 1.day.from_now)
Есть несколько других вещей, которые вы должны знать при обслуживании частного контента на CloudFront:
- В настройках поведения кэша для вашего шаблона пути (не обязательно по умолчанию) установите: «Ограничить доступ к просмотру (Использовать подписи или Подписанные файлы cookie)» на «Да»
- Установить «Надежный Signers "to" self "
- Установите« Query String Forwarding and Caching »на« Переслать все, кеш на основе всех », если вы хотите использовать другие строки запроса больше, чем подпись CloudFront в вашем URL-адресе, например
response-content-disposition
и response-content-type
(Я смог заставить их работать успешно, но они должны быть правильно установлены url_encoded.)
- В настройках Origin для CloudFront задайте свой идентификатор доступа и установите «Разрешения на получение прав на ведро» на «Да, обновить политику ведра»,
- В настройках общего распространения убедитесь, что «Состояние распространения» «Включено», и что вы добавили CNAME в «Альтернативные имена доменов (CNAME)», если вы используете его.
- Если вы используете CNAME, убедитесь, что ваш DNS настроен правильно, чтобы указать его на имя вашего CloudFront.
- Наконец, после установки конфигураций существует долгое ожидание, в то время как AWS обновляет дистрибутив, поэтому вы не увидите, как ваши изменения произойдут сразу. Может показаться, что ваше приложение/веб-сайт все еще сломан, пока изменения не распространяются через CloudFront. Это может затруднить настройку, потому что, если вы ошибаетесь, вам придется долго ждать, прежде чем вы сможете увидеть, как ваши изменения вступают в силу, и вы не можете быть уверены, что произошло. Но с этими настройками я смог заставить его работать на меня.
- Вы также можете создать несколько шаблонов пути кэширования, чтобы некоторый контент был приватным и ему нужен подписанный URL CloudFront, а другой контент - нет. Например, я устанавливаю шаблон пути
*.mp4
, который требует подписи для всех файлов mp4 и помещает его выше по умолчанию. И тогда у меня установлен режим кэширования по умолчанию, чтобы НЕ требовать подписанные URL-адреса, что позволяет публично открывать все другие файлы, такие как изображения, через дистрибутив CloudFront.
Если я использую эту настройку: 'fog_host', то я получаю эту ошибку: undefined method' fog_host = 'для CarrierWave :: Uploader :: Base: Class. Какую версию несущей поддерживают люди? –
Вы должны использовать 'config.asset_host' вместо' config.fog_host'. Я добавил этот вопрос к вопросу. Удачи! – hyperrjas
Да, я заметил, что после некоторого рытья :) Спасибо. –