감상문
CORS
ihl
2021. 10. 11. 00:26
CORS 오류는 백엔드와 프론트엔드를 연동하려할 때 흔하게 볼 수 있는 오류이다. 이 오류가 왜 발생하는지, 어떻게 해결할 수 있는지 알아보자.
- SOP(Same Origin Policy) : 다른 출처의 리소스를 사용하는 것에 제한을 두는 보안 방식
- Protocol-Host-Port가 같다면 같은 출처이다.
- IE는 Port가 달라도 같은 출처로 취급한다.
- Host는 String Value로 비교된다.
- http://localhost !== http://127.0.0.1 다른 출처
- http://localhost/api/cors === http://localhost 동일 출처
- SOP를 쓰는 이유
- 자신의 출처와 다른 곳에서 온 요청이 오면 안전한 요청인지 장담할 수 없기 때문에
- Protocol-Host-Port가 같다면 같은 출처이다.
- CORS(Cross Origin Resource Saring) : 추가 HTTP 헤더를 사용하여 한 출처에서 실행중인 웹 애플리케이션이 다른 출처의 선택한 자원에 접근할 수 있는 권한을 부여하도록 브라우저에 알려주는 체제
- CORS 접근제어 시나리오
- Preflight Request : Options 메서드를 통해 다른 도메인의 리소스에 요청이 가능한지 확인
- 본 요청을 보내기 전에 요청을 보내도 되는지 Options 메서드를 통해 사전 확인 작업
- 요청이 가능하다는 응답을 받은 후에 실제 요청을 보낸다.
- Preflight 요청 Header Format
- Origin: 요청 출처
- Access-Control-Request-Method: 실제 요청의 메서드
- Access-Control-Request-Headers: 실제 요청의 추가 헤더
- Preflight 응답 Header Format
- Access-Control-Allow-Origin: 서버 측 허가 출처
- Access-Control-Allow-Methods: 서버 측 허가 메서드
- Access-Control-Allow-Headers: 서버 측 허가 헤더
- Access-Control-Max-Age: Preflight 응답 캐시 기간
- Preflight 요청에 대해 브라우저에서 캐싱해두고, 다음에 같은 곳으로 요청을 보낼 때 Preflight요청을 보내지 않고 바로 실제 요청을 보낸다.
- Preflight 응답이 가져야하는 특징
- 응답 코드는 200 대여야 한다.
- 응답 Body는 비어있는 것이 좋다.
- Preflight가 필요한 이유 : CORS를 모르는 서버의 안전을 위해서
- delete 같은 요청이 왔을 때 이를 바로 처리한 후 브라우저에 CORS 오류를 발생시키면 서버는 이미 DB 내용을 지웠기 때문에 늦는다. 따라서 미리 preflight를 보내보고 cors 오류를 발생시키고 본 요청을 보내지 않아야 서버도 안전하다.
- Simple Request : Preflight 없이 바로 실제 요청을 보낸다.
- 조건
- 메서드 : GET, POST, HEAD
- Content-Type : application/x-www-form-urlencoded, multipart/form-data, text/plain
- Header : Accept, Accept-Language, Content-Language, Content-Type
- 조건
- 인증정보 포함 요청(Credentialed) : 인증 관련 헤더 정보(쿠키, 토큰..)가 포함된 요청
- 클라이언트는 credentials : include 를 설정하여 요청
- 서버는 Access-Control-Allow-Credentials: true를 설정
- Access-Control-Allow-Origin: * 이 아니어야 한다.
- Preflight Request : Options 메서드를 통해 다른 도메인의 리소스에 요청이 가능한지 확인
- CORS 접근제어 시나리오
- CORS 오류 해결방법
- 프론트 프록시 서버 설정 (개발환경)
- 브라우저에서는 같은 출처로 보내도록 만들고, 프론트 서버에서 다른 출처로 보내게 만든다.
- 브라우저 요청
- origin: example.com:1000
- target(FE Server): example:1000/api
- 브라우저 입장에서는 같은 origin, target 이므로 cors 오류가 발생하지 않는다.
- FE Server
- origin: example:1000
- target(BE Server): example:2000/api
- 브라우저 요청
- 브라우저에서는 같은 출처로 보내도록 만들고, 프론트 서버에서 다른 출처로 보내게 만든다.
- 직접 헤더에 설정
- 스프링 부트 설정
- 프론트 프록시 서버 설정 (개발환경)