1. SOP (Same Origin Policy)
다른 출처의 리소스를 사용하는 것에 제한하는 보안 방식입니다. Origin가 무엇을 의미하는지 알아봅시다.
앞서 URL에 대해 작성한 글에서도 확인할 수 있듯이, URL의 Protocol, Host, Port이 같은 경우 동일 출처라고 합니다.
tip) http 기본 포트가 80 포트입니다.
tip) 127.0.0.1은 localhost가 맞지만, 브라우저 입장에서는 string value를 비교하기 때문에, http://localhost:80 과 http://127.0.0.1 은 다른 출처로 인식한다고 합니다.
2. 다른 출처의 리소스
CORS로 해결합니다. Cross-Origin Resource Sharing은 추가 HTTP 헤더를 사용하여, 한 출처에서 실행 중인 웹 애플리케이션이 다른 출처의 선택한 자원에 접근할 수 있는 권한을 부여하도록 브라우저에 알려주는 체제입니다. CORS 접근제어 시나리오 3가지를 알아봅시다.
(1) Simple Request
단순 요청입니다. Preflight 요청 없이 바로 요청을 날립니다.
Simple request의 조건은 다음과 같습니다.
- GET, POST, HEAD 메서드 중 하나
- Content-Type는 application/x-www-form-urlencoded, multipart/form-data, text/plain 중 하나
- 헤더는 Accept, Accept-Language, Content-Language, Content-Type만 허용
(2) Preflight Request
프리플라이트 요청입니다. 사전 확인 작업이라고 생각하면 좋습니다.
- OPTIONS 메서드를 통해 다른 도메인의 리소스에 요청이 가능한 지 확인
- 요청이 가능하다면 실제 요청(Actual Request)를 보냅니다.
Prefligtht request에서 확인하는 것은 다음과 같습니다.
- Origin: 요청 출처
- Access-Control-Request-Method: 실제 요청의 메서드
- Access-Control-Request-Headers: 실제 요청의 추가 헤더
Prefligtht response는 다음과 같습니다.
- Access-Control-Allow-Origin: 서버 측 허가 출처
- Access-Control-Allow-Methods: 서버 측 허가 메서드
- Access-Control-Allow-Headers: 서버 측 허가 헤더
- Access-Control-Max-Age: Preflight 응답 캐시 시간
Preflight response가 가져야 하는 특징은 다음과 같습니다
- 응답 코드는 200대
- 응답 바디는 비어있는 것이 좋습니다.
(3) Credentialed Request
인증 정보 포함 요청입니다. 인증 관련 헤더를 포함할 때 사용하는 요청입니다.
- 클라이언트: credentials: include로 하면, 클라이언트가 자동으로 쿠키나 jwt를 포함해서 요청을 보냅니다.
- 서버: Access-Control-Allow-Credentials: true로 하면, 클라이언트가 요청한 것을 받을 수 있습니다. 추가로, Access-Control-Allow-Origin: * 은 에러를 뿜습니다. 그래서 정확한 Origin을 줘야합니다.
(4) CORS 해결하는 방법
- 프론트 프록시 서버 설정
- 직접 헤더에 설정해주기
(5) 공식 문서
https://developer.mozilla.org/ko/docs/Web/HTTP/CORS