Przejdź do głównej zawartości

CORS - co to jest i kiedy sprawia problemy

Co przekazesz słuchaczom?

Słuchacze zrozumieja, czym jest CORS (Cross-Origin Resource Sharing), dlaczego przegladarki blokuja niektore zadania oraz jak prawidłowo skonfigurować serwer, aby umozliwic bezpieczna komunikacje miedzy roznymi domenami.

  1. Wprowadzenie (2 min) - Czym jest Same-Origin Policy i dlaczego istnieje
  2. Teoria: CORS (2 min) - Mechanizm zezwalania na cross-origin requests
  3. Teoria: Preflight (2 min) - Kiedy przegladarka wysyła OPTIONS
  4. Demo praktyczne (4 min) - Błąd CORS w konsoli i jego rozwiązanie
  5. Podsumowanie (2 min) - Najczestsze błędy i dobre praktyki

Co to jest Same-Origin?

Dwa URL-e maja to samo origin, gdy maja identyczne:

  • Protokół (http vs https)
  • Domena (example.com vs api.example.com)
  • Port (80 vs 8080)

Przegladarka blokuje JavaScript przed dostepem do zasobow z innego origin że wzgledow bezpieczeństwa.

URL AURL BSame Origin?
https://example.com/pagehttps://example.com/apiTak
https://example.comhttp://example.comNie (protokół)
https://example.comhttps://api.example.comNie (subdomena)
https://example.com:443https://example.com:8080Nie (port)

Simple Request - przegladarka od razu wysyła zadanie:

Warunki prostego requestu:

  • Metoda: GET, HEAD lub POST
  • Nagłówki: tylko standardowe (Accept, Content-Type itp.)
  • Content-Type: text/plain, application/x-www-form-urlencoded lub multipart/form-data
GET /api/data HTTP/1.1
Host: api.example.com
Origin: https://frontend.com
---
HTTP/1.1 200 OK
Access-Control-Allow-Origin: https://frontend.com
Content-Type: application/json

Response Headers

  • Access-Control-Allow-Origin - dozwolone origin(y)
  • Access-Control-Allow-Methods - dozwolone metody HTTP
  • Access-Control-Allow-Headers - dozwolone nagłówki
  • Access-Control-Allow-Credentials - czy cookies dozwolone
  • Access-Control-Max-Age - czas cachowania preflight
  • Access-Control-Expose-Headers - nagłówki dostepne dla JS

Request Headers

  • Origin - skad pochodzi request (automatycznie)
  • Access-Control-Request-Method - metoda do użycia (preflight)
  • Access-Control-Request-Headers - nagłówki do użycia (preflight)

Diagram pokazujacy:

  • Strona na domenie A (np. frontend.com)
  • Strzałka do API na tej samej domenie - DOZWOLONE (zielona)
  • Strzałka do API na innej domenie - ZABLOKOWANE (czerwona)
  • Informacja: “Przegladarka chroni użytkownika”

Schemat sekwencyjny:

  1. Przegladarka -> Serwer: Request z nagłówkiem Origin
  2. Serwer -> Przegladarka: Response z Access-Control-Allow-Origin
  3. Przegladarka: Sprawdza czy origin pasuje
  4. JavaScript: Dostaje dane (lub błąd)

Diagram pokazujacy dwa requestty:

  1. OPTIONS (preflight) - “Czy mogę?”
  2. Właściwy request - “Wysyłam dane” Z zaznaczeniem, że preflight jest cachowany (Max-Age)

Screenshot z konsoli przegladarki z bledem:

Access to fetch at 'https://api.example.com/data' from origin
'https://frontend.com' has been blocked by CORS policy
  1. Utworz plik HTML na localhost:3000
  2. Dodaj fetch do API na localhost:8080
  3. Otworz DevTools (F12) -> Console
  4. Pokaz błąd “blocked by CORS policy”
  5. Pokaz w Network, że request został wysłany (serwer go dostał!)
<!-- index.html na localhost:3000 -->
<!DOCTYPE html>
<html>
<head><title>CORS Demo</title></head>
<body>
<h1>CORS Test</h1>
<button onclick="fetchData()">Pobierz dane</button>
<pre id="result"></pre>
<script>
async function fetchData() {
try {
// To wywoła błąd CORS jeśli serwer nie ma odpowiednich nagłówków
const response = await fetch('http://localhost:8080/api/data');
const data = await response.json();
document.getElementById('result').textContent = JSON.stringify(data, null, 2);
} catch (error) {
document.getElementById('result').textContent = 'Błąd: ' + error.message;
console.error('CORS Error:', error);
}
}
</script>
</body>
</html>
  1. Pokaz kod serwera bez nagłówków CORS
  2. Dodaj nagłówek Access-Control-Allow-Origin
  3. Zrestartuj serwer
  4. Pokaz, że teraz request działa
<?php
// api.php na localhost:8080 - PRZED (bez CORS)
header('Content-Type: application/json');
echo json_encode(['message' => 'Hello from API']);
<?php
// api.php na localhost:8080 - PO (z CORS)
header('Content-Type: application/json');
header('Access-Control-Allow-Origin: http://localhost:3000');
// Obsługa preflight
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
header('Access-Control-Allow-Methods: GET, POST, OPTIONS');
header('Access-Control-Allow-Headers: Content-Type');
exit(0);
}
echo json_encode(['message' => 'Hello from API']);
  1. Zmien request na POST z Content-Type: application/json
  2. Pokaz w DevTools dwa requesty (OPTIONS + POST)
  3. Omow, dlaczego preflight jest potrzebny

Wymagania minimalne:

  • Wyjasnij Same-Origin Policy i po co istnieje
  • Opisz czym jest CORS i jaki problem rozwiązuje
  • Pokaz 1 schemat komunikacji
  • Pokaz przykład błędu w konsoli
Ocena: 3.0 (minimum)

Pytanie 1

Dlaczego curl i Postman nie maja problemow z CORS, a przegladarka tak?

Pytanie 2

Czy ustawienie Access-Control-Allow-Origin: * jest bezpieczne? W jakich przypadkach?

Pytanie 3

Co się stanie, jeśli serwer nie obsługuje metody OPTIONS?

Pytanie 4

Jak CORS wpływa na bezpieczeństwo aplikacji webowych?

Whitelist origins

Zdefiniuj liste dozwolonych origin i sprawdzaj przychodzacy nagłówek Origin.

Ogranicz metody

Nie dawaj * - wymien tylko te metody HTTP, które naprawde potrzebujesz.

Ustaw Max-Age

Cachuj odpowiedzi preflight, aby zmniejszyc liczbe requestow OPTIONS.

Testuj w przegladarce

Postman nie testuje CORS - zawsze sprawdzaj w prawdziwej przegladarce.