Cross-Origin Resource Sharing로 교차 출처 리소스 공유
서로 다른 Origin을 가진 Application이 서로의 Resource에 접근할 수 있도록 해줌
프로토콜, 호스트, 포트 를 통틀어 Origin 이라고 함즉, 여기서 하나라도 다르면 Cross Origin이 됨보안상의 이유로 Cross Origin HTTP Request를 제한함
하지만 한 서버에서 데이터와 정적파일을 같이 렌더링해 사용자의 요청을 처리하는것이 아닌 프런트 서버와 api 서버를 분리하여 통신한다면 Cross-Origin 이므로 오류가 발생할 것이다.
출처(Origin)란 URL 구조에서 살펴본 Protocal, Host, Port를 합친 것을 말합니다. 브라우저 개발자 도구의 콘솔 창에 location.origin
를 실행하면 출처를 확인할 수 있습니다.
같은 출처인지 다른 출처인지 이해를 돕기 위해 예제를 하나 살펴보도록 하겠습니다. 현재 웹페이지의 주소가 https://jungmin.github.io/tech/
일 때 같은 출처인지 다른 출처인지 아래 테이블과 같은 결과를 얻을 수 있습니다.
URL | 결과 | 이유 |
---|---|---|
https://jungmin.github.io/about |
같은 출처 | Protocal, Host, Port 동일 |
https://jungmin.github.io/about?q=work |
같은 출처 | Protocal, Host, Port 동일 |
https://jungmin.github.io/about#work |
같은 출처 | Protocal, Host, Port 동일 |
http://jungmin.github.io |
다른 출처 | Protocal 다름 |
https://jungmin.github.io:81/about |
다른 출처 | Port 다름 |
https://jungmin.heroku.com |
다른 출처 | Host 다름 |
Postman으로 API를 테스트하거나, 다른 서버에서 API를 호출할 때는 멀쩡히 잘 동작하다가 브라우저에서 API를 호출할 때만 CORS policy
오류가 발생해서 당혹스러울 때가 있으셨을 수도 있습니다. 그 이유는 브라우저가 동일 출처 정책(Same-Origin Policy, SOP)를 지켜서 다른 출처의 리소스 접근을 금지하기 때문입니다. 하지만 실제로 웹페이지는 상당히 자주 다른 출처의 리소스를 사용해야 합니다. 예를 들어 jungmin.github.io
라는 도메인 주소를 사용하는 웹페이지에서 jungmin-api.github.io
라는 API 서버로 데이터를 요청해서 화면을 그린다면 이 웹페이지는 동일 출처 정책을 위반한 것이 됩니다.
동일 출처 정책을 지키면 외부 리소스를 가져오지 못해 불편하지만, 동일 출처 정책은 XSS나 XSRF 등의 보안 취약점을 노린 공격을 방어할 수 있습니다. 하지만 현실적으로는 외부 리소스를 참고하는 것은 필요하기 때문에 외부 리소스를 가져올 수 있는 방법이 존재해야 합니다. 외부 리소스를 사용하기 위한 SOP의 예외 조항이 CORS입니다.
CORS의 동작 방식은 단순 요청 방법과 예비 요청을 먼저 보내는 방법 2가지 방법이 있습니다.