Po kilku poszukiwaniach i zmaganiach z tym przez długi czas znalazłem stronę, która mówi, że CarrierWave nie obsługuje adresów URL podpisanych przez CloudFront. Podpisane adresy URL CloudFront różnią się od adresów URL podpisanych przez S3, co spowodowało pewne zamieszanie. Kiedy już to rozgryzłem, o wiele łatwiej było wiedzieć, co robić.
przypadku skonfigurowania CarrierWave z config.fog_public = false
następnie zostanie ona automatycznie rozpocząć podpisywanie URL-S3, ale nie może być skonfigurowany do pracy z Fog
i CloudFront prywatnych treści w wersji CarrierWave używam (1.0.0)
. Próbowałem nawet użyć klejnotu carrierwave-aws
i to też nie pomogło.
Więc co by się stało, jest to, że CarrierWave podpisze URL i gospodarz będzie wyglądać mniej więcej tak:
https://my_bucket_name.s3-us-west-2.amazonaws.com/uploads/...?signature...
że punkty bezpośrednio do wiadra S3, ale potrzebowałem go, aby wskazywał CloudFront. Potrzebowałem gościć wyglądać następująco:
https://s3.cloudfront_domain_name.com/uploads/...
A co by się stało, gdybym ustawić config.asset_host
równą mojej lokalizacji CloudFront to bym się tym (podwójne ukośniki przed „aktualizacje”):
https://s3.cloudfront_domain_name.com//uploads/...
To także wyraźnie pokazało, że CarrierWave nie został jeszcze zaprojektowany do użycia z CloudFront. Mam nadzieję, że go poprawią. To była moja praca. To brzydkie, ale udało się zrobić to, czego potrzebowałem, bez potrzeby modyfikacji samego CarrierWave, ponieważ mam nadzieję, że CarrierWave w pewnym momencie doda wsparcie dla CloudFront.
- Najpierw zrobiłem regex Znajdź/Zamień na mój adres URL i usunął część hosta S3 i umieścić na mojej części hosta CloudFront.
cf_url = s3_url.gsub("my_bucket_name.s3-us-west-2.amazonaws.com", "s3.cloudfront_domain_name.com")
- Następny zrobiłem kolejny regex znaleźć/zastąpić usunąć S3 podpisane url na końcu łańcucha:
non_signed_cf_url = cf_url.gsub(/\?.+/, '')
To dlatego, że podpis będzie nieprawidłowa, ponieważ był za pomocą interfejsu API do S3, a nie dla CloudFront dla podpisywanie adresu URL.
- Teraz ponownie podpisać URL siebie, używając
cloudfront-signer
GEM: signed_cf_url = Aws::CF::Signer.sign_url(non_signed_cf_url, :expires => 1.day.from_now)
Istnieje kilka innych rzeczy, które trzeba mieć świadomość, gdy służąc treść prywatnej na CloudFront:
- W ustawieniach Zachowania pamięci podręcznej dla wzorca ścieżki (niekoniecznie domyślnego) ustaw: "Ogranicz dostęp do przeglądarki (Użyj podpisanych adresów URL lub Podpisanych plików cookie)" na "Tak"
- Zestaw "Zaufany Osoby podpisujące się "na" siebie "
- Ustaw" Przekazywanie i buforowanie ciągów kwerend "na" Prześlij wszystkie, pamięć podręczną na podstawie wszystkich ", jeśli chcesz używać innych zapytań bardziej niż podpis CloudFront w adresie URL, na przykład
response-content-disposition
i response-content-type
(Udało mi się je poprawnie uruchomić, ale muszą być poprawnie poprawione.)
- W ustawieniach CloudFront Origin ustaw swoją tożsamość dostępową i ustaw "Przyznaj prawa odczytu na wiadrze" na "Tak, zaktualizuj zasady wiadra"
- W ogólnych ustawieniach dystrybucji upewnij się, że "Stan dystrybucji" ma wartość "Włączone", a dodatek CNAME został dodany do "Alternatywne nazwy domen (CNAME)", jeśli używasz tego.
- Jeśli używasz rekordu CNAME, upewnij się, że Twój DNS jest poprawnie skonfigurowany tak, aby wskazywał go na nazwę dystrybucji CloudFront.
- Na koniec, po skonfigurowaniu konfiguracji długo czekać, podczas gdy AWS aktualizuje dystrybucję, więc zmiany nie będą widoczne od razu. Może się wydawać, że twoja aplikacja/strona internetowa wciąż jest uszkodzona, dopóki zmiany nie będą rozpowszechniane za pośrednictwem CloudFront. Może to utrudnić konfigurację, ponieważ jeśli źle zrobisz, musisz długo czekać, zanim zauważysz, że zmiany odniosły skutek i możesz nie wiedzieć, co się stało. Ale dzięki tym ustawieniom mogłem sprawić, żeby działał dla mnie.
- Można także utworzyć więcej niż jeden wzór ścieżki buforowania, aby niektóre treści były prywatne i wymagały podpisu podpisanego CloudFront, a inne nie. Na przykład ustawiłem ścieżkę
*.mp4
wymagającą podpisu dla wszystkich plików mp4 i umieszczonego powyżej domyślnego zachowania. A następnie mam domyślne zachowanie pamięci podręcznej NIE wymagające podpisanych adresów URL, dzięki czemu wszystkie inne pliki - takie jak obrazy - będą publicznie dostępne za pośrednictwem dystrybucji CloudFront.
Jeśli używam tego ustawienia: 'fog_host', to pojawia się ten błąd: niezdefiniowana metoda' fog_host = 'dla CarrierWave :: Uploader :: Base: Class Jaką wersję nosicieli noszą użytkownicy? –
Powinieneś użyć 'config.asset_host' zamiast' config.fog_host'. Dodałem ten problem do pytania. Powodzenia! – hyperrjas
Tak, zauważyłem to, po pewnym kopaniu :) Dzięki. –