Jak włączyć CORS podczas dostępu do kontenerów Object Storage na NSIS Cloud
Podczas uzyskiwania dostępu do obiektów przechowywanych w kontenerze Object Storage z innej domeny, przeglądarka może zablokować żądanie z powodu ograniczeń Cross-Origin Resource Sharing (CORS).
CORS definiuje mechanizm, który umożliwia aplikacjom webowym żądanie zasobów z innego pochodzenia. Jeśli usługa docelowa (na przykład endpoint S3 w NSIS Cloud) nie zwróci wymaganych nagłówków CORS, przeglądarka odrzuci żądanie i wyświetli błędy takie jak:
Header «Access-Control-Allow-Origin» missing
CORS preflight channel did not succeed
Access to XMLHttpRequest has been blocked by CORS policy
W tej procedurze opisano, jak włączyć CORS na punkcie końcowym S3 oraz jak zweryfikować poprawność konfiguracji.
Ważne
Na chmurze NSIS Cloud zazwyczaj dostępne są dwa endpointy służące do dostępu do Object Storage:
Swift-style URL (zawierający /swift/v1/…)
S3-style URL (bucket bezpośrednio pod endpointem S3)
Komenda s3cmd setcors ma zastosowanie wyłącznie do endpointu S3. Żądania CORS wysyłane na adres Swift nie zwrócą nagłówków CORS.
Co omówimy
Wymagania wstępne
Nr 1 Konto
Konto hostingowe NSIS Cloud z dostępem do interfejsu Horizon: https://horizon.cloudferro.com/.
Nr 2 Kontener Object Storage
Na chmurze NSIS Cloud musi istnieć co najmniej jeden kontener. Zobacz: Jak korzystać z Object Storage w NSIS.
Przykładowy kontener: container-nr-1, zawierający file-nr-1.txt i file-nr-2.txt.
Włącz Public Access w Horizon, aby uzyskać link do kontenera.
Ostrzeżenie
Przykładowe adresy URL dla regionu WAW4-1:
Kontener: https://s3.waw4-1.cloudferro.com/container-nr-1/
Obiekt: https://s3.waw4-1.cloudferro.com/container-nr-1/file-nr-1.txt
Zastąp te wartości właściwymi dla Twojego środowiska. Nie używaj adresów Swift (/swift/v1/…) do testów CORS.
Nr 3 Klient OpenStack CLI
Jeśli chcesz korzystać z chmury NSIS Cloud za pomocą klienta OpenStack CLI, musisz go zainstalować. Zobacz jeden z poniższych artykułów:
Po instalacji oprogramowania należy się uwierzytelnić, aby rozpocząć pracę: Jak aktywować dostęp OpenStack CLI do chmury NSIS przy użyciu uwierzytelniania dwuskładnikowego
Aby sprawdzić, czy polecenie openstack działa poprawnie, wyświetl listę flavorów:
openstack flavor list
Nr 4 Poświadczenia EC2 (S3), s3cmd i plik konfiguracyjny
Wygeneruj poświadczenia EC2 zgodnie z artykułem: Jak wygenerować poświadczenia EC2 i zarządzać nimi na NSIS Cloud.
Poświadczenia EC2 / S3 są powiązane z projektem. Muszą być utworzone w tym samym projekcie, w którym znajduje się kontener. W przeciwnym wypadku operacje S3 zakończą się błędem 403 AccessDenied.
Wygeneruj poświadczenia:
openstack ec2 credentials create -f json
Z wyniku skopiuj wartości access i secret.
Utwórz i zapisz plik konfiguracyjny jdoe-test-s3cfg z parametrami dla regionu WAW4-1:
# File: jdoe-test-s3cfg
access_key = <access>
secret_key = <secret>
host_base = s3.waw4-1.cloudferro.com
host_bucket = s3.waw4-1.cloudferro.com
bucket_location = dias_default
use_https = True
signature_v2 = True
host_bucket – zapewnia dostęp w trybie ścieżkowym
signature_v2 – umożliwia zgodność z klasycznymi podpisami S3
bucket_location – odzwierciedla typową konfigurację regionu
Zweryfikuj połączenie z S3:
s3cmd -c jdoe-test-s3cfg ls
Jeśli otrzymasz 403 AccessDenied, upewnij się, że:
poświadczenia zostały utworzone w tym samym projekcie co kontener
adres endpointu (s3.waw4-1.cloudferro.com) jest poprawny
kontener rzeczywiście istnieje
Jeśli s3cmd nie jest zainstalowany, zobacz: Jak uzyskać dostęp do object storage z NSIS za pomocą s3cmd
Nr 5 Python 3 i lokalny serwer HTTP do testów
Strona testowa HTML musi być otwierana przez HTTP. Jeśli zostanie otwarta bezpośrednio z dysku (file://), przeglądarka przypisze jej pochodzenie null, co uniemożliwi poprawną ocenę CORS.
Python 3 udostępnia prosty serwer HTTP. Przejdź do katalogu zawierającego plik test-cors.html i uruchom:
python3 -m http.server 8000
Następnie otwórz w przeglądarce:
http://localhost:8000/test-cors.html
Przegląd procedury
Procedura składa się z następujących kroków:
Zapisz lokalnie stronę testową CORS.
Uruchom ją przez HTTP zamiast file://.
Przetestuj najpierw adres Swift (aby zaobserwować ograniczenie CORS).
Zastosuj konfigurację CORS w buckecie poleceniem s3cmd setcors.
Powtórz test z adresem S3 (aby potwierdzić, że CORS działa).
Informacja
Zachowanie CORS można obserwować wyłącznie w przeglądarce. Narzędzia CLI, takie jak curl czy s3cmd, nie podlegają tym ograniczeniom.
Krok 1 – Utwórz stronę testową odtwarzającą błąd CORS
Przed włączeniem CORS należy sprawdzić zachowanie przeglądarki, gdy CORS nie jest skonfigurowany.
Utwórz prostą stronę HTML, która celowo wywoła błąd CORS. Posłuży ona do zobrazowania komunikatu „blocked by CORS policy” przed zastosowaniem konfiguracji.
Strona testowa jest oparta na przykładzie z dokumentacji OpenStack Swift: https://docs.openstack.org/swift/latest/cors.html#test-cors-page
Zapisz poniższą zawartość jako test-cors.html:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Test CORS</title>
</head>
<body>
Token<br><input id="token" type="text" size="64"><br><br>
Method<br>
<select id="method">
<option value="GET">GET</option>
<option value="HEAD">HEAD</option>
<option value="POST">POST</option>
<option value="DELETE">DELETE</option>
<option value="PUT">PUT</option>
</select><br><br>
URL (Container or Object)<br><input id="url" size="64" type="text"><br><br>
<input id="submit" type="button" value="Submit" onclick="submit(); return false;">
<pre id="response_headers"></pre>
<hr>
<pre id="response_body"></pre>
<script type="text/javascript">
function submit() {
var token = document.getElementById('token').value;
var method = document.getElementById('method').value;
var url = document.getElementById('url').value;
document.getElementById('response_headers').textContent = null;
document.getElementById('response_body').textContent = null;
var request = new XMLHttpRequest();
request.onreadystatechange = function () {
if (request.readyState == 4) {
var responseHeaders = 'Status: ' + request.status;
responseHeaders += '\\nStatus Text: ' + request.statusText;
responseHeaders += '\\n\\n' + request.getAllResponseHeaders();
document.getElementById('response_headers').textContent = responseHeaders;
document.getElementById('response_body').textContent = request.responseText;
}
}
request.open(method, url);
if (token != '') {
request.setRequestHeader('X-Auth-Token', token);
}
request.send(null);
}
</script>
</body>
</html>
Ten plik zostanie użyty:
najpierw do odtworzenia błędu „Access-Control-Allow-Origin missing”
następnie do potwierdzenia działania CORS po zastosowaniu konfiguracji
Krok 2 – Uruchom plik przez HTTP
Uzyskaj dostęp do strony testowej za pomocą lokalnego serwera HTTP skonfigurowanego wcześniej.
Otwórz w przeglądarce:
http://localhost:8000/test-cors.html
Krok 3 – Test z adresem Swift
Wprowadź adres w stylu Swift:
https://s3.waw4-1.cloudferro.com/swift/v1/container-nr-1/
Pojawi się błąd CORS, co potwierdza, że nagłówki nie są zwracane przez endpoint Swift.
Krok 4 – Sprawdź aktualny status CORS
s3cmd -c jdoe-test-s3cfg info s3://container-nr-1
Wartość CORS: powinna wynosić none.
Krok 5 – Utwórz konfigurację CORS
<CORSConfiguration>
<CORSRule>
<AllowedOrigin>*</AllowedOrigin>
<AllowedMethod>GET</AllowedMethod>
<AllowedHeader>*</AllowedHeader>
</CORSRule>
</CORSConfiguration>
Krok 6 – Zastosuj CORS do bucketu
s3cmd -c jdoe-test-s3cfg setcors cors.xml s3://container-nr-1
s3cmd -c jdoe-test-s3cfg info s3://container-nr-1
Krok 7 – Zweryfikuj konfigurację CORS
https://s3.waw4-1.cloudferro.com/container-nr-1/file-nr-1.txt
Wyniki
Po wykonaniu powyższych kroków Twój bucket S3 jest skonfigurowany z polityką CORS, która umożliwia dostęp do obiektów z innych domen.
Rozwiązywanie problemów
Jeśli s3cmd zgłasza błąd 403 AccessDenied, upewnij się, że dane uwierzytelniające EC2 zostały wygenerowane w tym samym projekcie co kontener.
Jeśli nagłówki CORS są skonfigurowane, ale żądania pozostają zablokowane, sprawdź, czy adres URL używa endpointu S3, a nie endpointu Swift.
Upewnij się, że nazwa hosta endpointu w konfiguracji jest zgodna z regionem. Na przykład, w artykule używaliśmy WAW4-1, więc odpowiadający mu endpoint w pliku konfiguracyjnym musiał brzmieć s3.waw4-1.cloudferro.com.
Aby włączyć dodatkowe metody HTTP, dodaj je w sekcji <AllowedMethod> w pliku cors.xml.
Jeśli na stronie testowej pojawia się Status: 0 z pustym tekstem statusu, upewnij się, że strona testowa jest obsługiwana przez HTTP (http://localhost:8000) i nie jest otwierana z dysku (file://).
Sprawdź, czy test wykonujesz względem adresu URL w stylu S3 (bez /swift/v1/), ponieważ nagłówki CORS nie są zwracane przez endpointy Swift.