SOP와 CORS
Origin(출처)
: 프로토콜, 도메인(호스트 이름), 포트로 구성됨
- 예
https:// www.myshop.com :8080
프로토콜(통신규약) 호스트 네임 포트 번호
- http는 :80
- https는 :443
- 기본포트 사용 시 생략 가능
SOP(Same Origin Policy)
: 같은 origin만 리소스를 공유할 수 있는 정책
- 필요성
: origin이 다른 두 app이 자유롭게 소통가능한 환경은 위험함
=> CSRF, CSS 공격을 받을 우려가 있음
- 특징
- 교차 origin HTTP 요청 직접 제한(다른 출처에 있는 리소스를 사용하는 것 제한)
- 예시
- https://www.myshop.com/example/
- https://www.myshop.com/example2/
=> SOP 부합: 프로토콜, 도메인, 포트 동일
- http://en.myshop.com/example2/
=> SOP 미부합: 프로토콜, 도메인 미일치
- 한계
- 다른 출처에 있는 리소스 사용 흔한 일이기 때문에 무작정 제한하는 것은 좋지 않음
=> CORS 정책 수립
Same-Orgin 정책을 지원하는 예시
- <link>태그의 href에서 타사 .css리소스에 접근 가능
- <img>태그의 src에서 타사 .png, .jpg 등의 리소스에 접근 가능
- <script>태그의 src에서 타사 .js 리소스에 접근 가능
- type = "module"인 경우는 불가능
CORS(Cross Origin Resource Sharing)
: 다른 출처의 자원이 SOP 위반해도 CORS 정책을 따르면 허용
- 동작 방식
1. 웹에서 HTTP 요청에 origin 헤더를 추가해 origin을 담아 서버로 보냄
2. 서버가 응답 헤더에 Access-Control-Allow-Origin에 해당 자원에 접근 가능한 origin을 담아 보냄
3. 브라우저가 교차 출처 응답에 대해 요청 헤더의 origin이 응답 헤더의 Access-Control-Allow-Origin에 적합한지 판단
- 적합: 자원 가져옴
- 부적합: 에러 출력(브라우저 측에서 출처를 비교, 차단함_서버 측이 아니라)
- 예시
- 'Access-Control-Allow-Origin': '*' => 모든 origin 허용
- 'Access-Control-Allow-Origin': 'null' => https://example.com에서만 온 요청 허용
Cross-Orgin 정책을 지원하는 예시
- <link>태그의 href에서 타사 .css리소스에 접근 가능
- <img>태그의 src에서 타사 .png, .jpg 등의 리소스에 접근 가능
- <script>태그의 src에서 타사 .js 리소스에 접근 가능
- type = "module"인 경우는 불가능
<실제 예시와 함께 살펴보기>
상황: main.html에서 js부분 분리해 main.js 파일 생성 후 main.html 파일 F5로 실행 => js파일 미작동
에러메세지
main.html:1 Access to script at 'file:///C:/2getherPrj/main.js' from origin 'null' has been blocked by CORS policy: Cross origin requests are only supported for protocol schemes: chrome, chrome-extension, chrome-untrusted, data, http, https, isolated-app.Understand this error main.js:1 Failed to load resource: net::ERR_FAILED |
main.html:1 Access to script at 'file:///C:/2getherPrj/main.js' from origin 'null' has been blocked by CORS policy
- 위 문구를 통해 해당 url이 CORS 정책에 의해 부적합 판단을 받고 에러가 뜬 것을 알 수 있음
해결1안
: 서버에서 Access-Control-Allow-Origin 헤더 설정(Node.js, Flask, Django 등의 백엔드 서버에서 CORS 설정 추가)
- html, css, js는 클라이언트 측 실행 코드 => 서버에 대한 요청만 보낼 수 있고 정책 설정 불가
해결2안
: LIVE SERVER로 실행