
서버랑 통신 하다보면 이런 에러가 자주 발생한다. 이 에러는 SOP 정책 때문에 생겨났다.
SOP는 Same-Origin Policy의 약자. 동일 출처 정책을 뜻한다. 같은 출처(Origin)의 리소스만 통신이 가능하다는 뜻이다.
프론트에서 발생하는 것이다. 브라우저 단에서 서로 다른 출처 간 통신을 기본 값으로 막는다.
- 프로토콜이 같아야 한다.
- 호스트가 같아야 한다.
- 포트가 같아야 한다.
- http프로토콜의 기본 포트는 :80
- https 프로토콜의 기본 포트는 :443
동일 출처 정책으로 잠재적인 공격 경로를 줄여준다. 다른 사이트와의 리소스 공유를 제한하기 때문에 정보가 타 사이트의 코드에 의해서 새어나가는 것을 방지할 수 있다.
이제는 다른 서버에 있는 API도 사용하는 세상이다. SOP를 조금 돌아갈 방법이 필요하다. 이것을 위해 필요한 것은 CORS. Cross-Origin Resource Sharing의 약자다. 교차 출처 리소스 공유를 의미한다.
추가 HTTP 헤더를 사용하여, 한 출처에서 실행 중인 웹 애플리케이션이 다른 출처의 선택한 자원에 접근할 수 있는 권한을 부여하도록 브라우저에게 알려주는 체제.
"Aceess-Control-Allow-Origin"
클라이언트가 실제 요청을 보내기 전, OPTIONS 메서드로 사전 요청을 보내 해당 출처 리소스에 접근 권한이 있는지부터 확인하는 것을 프리플라이트 요청이라고 한다.
- 실제 요청을 보낸다.
- Preflight로 서버에 먼저 간단한 헤더 정보로 권한을 줄 수 있는지 확인하고 브라우저로 응답을 보낸다.
- 그 응답이 제대로 온다면 실제 요청을 서버에 보낸다.
- 서버는 요청을 수행해서 Response를 Client에 전달한다.
요청을 보낸 출처가 접근 권한이 없다면?
- 실제 요청을 보낸다.
- Prefilght로 서버에 요청을 보낸다.
- 서버는
Access-Control-Allow-Origin헤더를 보고 없으면 에러를 낸다.- 그 에러는 바로 CORS 에러
프리플라이트가 필요한 이유
- 실제 요청을 보내기 전에 미리 권한을 확인하기 때문에 리소스 측면에서 효율적.
- CORS에 대비가 되어있지 않은 옛날 서버는 보호가 가능하다. CORS 권한이 없다는 것을 프리플라이트가 판단해서 통신을 차단한다.
이러한 이유로 프리플라이트 요청이 CORS의 기본 사양이 되었다.
특정 조건이 만족되면 프리플라이트 요청을 생략하고 요청을 보내는 것.
GET,HEAD,POST요청 중 하나여야 한다.- 자동으로 설정되는 헤더 외에,
Accept,Accept-Language,Content-Language,Content-Type헤더의 값만 수동으로 설정할 수 있다.
Content-Type헤더에는application/x-www-form-urlencoded, multipart/form-data, text/plain 값만 허용된다.
요청 헤더에 인증 정보를 담아 보낼 수 있게 설정하는 것이다. 출처가 다르면 별도의 설정을 통해 쿠키를 보낼 수 있다. 설정을 하지 않으면 쿠키를 보낼 수 없다.
민감 정보이기 때문에 클라이언트와 서버 둘 다 설정을 해줘야 한다.
- 클라이언트 측에서는 요청 헤더에
withCreadentials: true를 넣어준다.- 서버 측에서 응답 헤더에
Access-Control-Allow-Credentials: true를 넣어준다.- 서버 측에서
Access-Control-Allow-Origin을 설정할 때, 모든 출처를 허용하는*로 설정하면 에러가 발생한다. 민감 정보이기 때문에 출처를 정확하게 설정해줘야 한다.