Marcin Kondras

Co to jest?

CORS (Cross Origin Resource Sharing) to mechanizm, który pozwala na wykonanie żądania HTTP na zastrzeżonych zasobach z serwera o innej domenie niż domena serwera, który udostępnia te zasoby. Obecnie przeglądarki stosują same-origin policy (SOP), która uniemożliwia jednej stronie internetowej na dostęp do drugiej, jeśli nie mają tego samego origin (źródła).

Czym jest origin? Pisałem o domenie, ale właściwie jest to kombinacja domeny, protokołu i portu – żeby przeglądarka zezwoliła na dostęp do innej strony, wszystkie 3 muszą być takie same. Np. mamy aplikację backendową, która udostępnia dane przez REST-a. Frontend chce pobrać te dane, więc zapewne użyje żądania Ajax (konkretnie żądania GET). Obie aplikacje działają na localhoście i używają protokołu HTTP, ale mają inny port. Backend więc nie udostępni danych.

Do czego służy SOP? Jest to ochrona przed atakami webowymi, np. gdy jedna, złośliwa strona chce zmodyfikować drzewo DOM drugiej. Jest to oczywiście przydatne, ale w przypadku tworzenia aplikacji może przeszkadzać, dlatego też należy używać CORS.

Jak działa?

Aplikacja kliencka wysyła żądanie HTTP do aplikacji o innym origin. Podaje przy tym w nagłówku żądania swój origin: Origin: http://localhost:3000 Aplikacja serwera, jeśli chce udzielić odpowiedzi, dodaje do odpowiedzi nagłówek: Allow-Control-Allow-Origin: http://localhost:3000, gdzie podany URL należy do aplikacji, która wysłała żądanie. Jeśli serwer chce udostępnić zasób każdej aplikacji wysyła header z gwiazdką: Allow-Control-Allow-Origin: *.

Wtyczka do przeglądarki

Żeby całkowicie ominąć to zabezpieczenie w Google Chrome, wystarczy zainstalować wtyczkę Allow-Control-Allow-Origin: * . Dodaje ona wyżej wspomniany nagłówek do odpowiedzi HTTP, co umożliwia zastosowanie CORS. Może się przydać przy developmencie aplikacji, ale raczej jej nie polecam przy zwykłym korzystaniu z Internetu.

CORS w backendzie. Java i Spring

Wrócę do wspomnianego przypadku, w którym frontend i backend komunikują się po REST, ale działają na różnych portach. Jak włączyć CORS w aplikacji Javowej?

W Springu mapujemy funkcje na żądania HTTP. W tym celu tworzymy RestController. Nie będę oczywiście tego opisywał, wspomnę tylko o tym, jak włączyć CORS. Wystarczy przed RestControllerem dodać adnotację @CrossOrigin, wtedy wszystkie żądania w nim zawarte będą obsługiwały CORS. Przykład:

@AllArgsConstructor
@RestController
@CrossOrigin
@RequestMapping("/device")
public class DeviceController {...

Żeby włączyć CORS jedynie w konkretnej metodzie należy przed nią umieścić adnotację

@CrossOrigin, np.
@CrossOrigin
@GetMapping()
public ResponseEntity<List<DeviceDTO>> getDevices() {
   return new ResponseEntity<>(deviceFacade.getDevices(), HttpStatus.OK);
}

Jeśli chcemy odpowiadać na żądania jedynie z konkretnych origins wpisujemy adnotację podając dozwolone URL-e, np. aplikacji frontendowej:

@CrossOrigin(origins = "http://localhost:3000")

Źródła

CORS

Spring: Enabling Cross Origin Requests for a RESTful Web Service

Allow-Control-Allow-Origin: * plugin