항상 개발할때마다 cors를 만나게 되는데 이제는 진짜 cors해결을 다 했다고 생각해서 다시 써본다.
Protocol, Host, Port를 합친걸 출처(Origin)라고 하는데 이 출처중에 하나라도 다르면 출처가 다르다고 판단되고 동일 출처 정책에 위반된다.
동일 출처 정책이란? 👉 동일 출처 정책
교차 출처 리소스 공유(Cross-Origin Resource Sharing).
추가 HTTP 헤더를 사용하여, 한 출처에서 실행 중인 웹 애플리케이션이 다른 출처의 선택한 자원에 접근할 수 있는 권한을 부여하도록 브라우저에 알려주는 체제
기본적으로 웹은 다른 출처의 리소스를 요청할 때는 HTTP 프로토콜을 사용하여 요청을 하는데,
이때 브라우저는 요청 헤더 (request header)에 Origin 필드에 요청을 보내는 출처를 담아 전송한다.
서버는 요청에 대한 응답을 하는데, 응답 헤더 (response header)에 Access-Control-Allow-Origin이라는 값에 '이 리소스를 접근하는 것이 허용된 출처'를 내려준다.
이후 응답을 받은 브라우저는 자신이 보냈던 요청의 Origin과 서버가 보내준 응답의 Access-Control-Allow-Origin을 비교해 본 후 이 응답이 유효한 응답인지 아닌지를 결정한다.
📌 이것이 기본적인 동작이지만 모든 CORS에서 이렇게 동작하진 않는다
CORS의 동작 방식은 단순 요청 방법과 예비 요청을 먼저 보내는 방법 2가지 방법이 있다.
Simple Reqeust는 서버에게 바로 요청을 보내는 방법이다.
단순 요청은 서버에 API를 요청하고, 서버는 Access-Control-Allow-Origin
헤더를 포함한 응답을 브라우저에 보냅니다. 브라우저는 Access-Control-Allow-Origin
헤더를 확인해서 CORS 동작을 수행할지 판단한다.
Preflight Reqeust는 서버에 예비 요청을 보내서 안전한지 판단한 후 본 요청을 보내는 방법이다.
실제 리소스를 요청하기 전에 OPTIONS
메서드로 서버에 예비 요청을 먼저 보내고, 서버는 이 예비 요청에 대한 응답으로 Access-Control-Allow-Origin
헤더를 포함한 응답을 브라우저에 보냅니다. 브라우저는 단순 요청과 동일하게 Access-Control-Allow-Origin
헤더를 확인해서 CORS 동작을 수행할지 판단합니다.
우선 다양한 해결방법이 있다.
그래서 내가 생각하는 좋은 방식은 2가지이다.
1. 서버에서 origin을 설정해주는것
서버에서 origin 자체를 정해줄 수 가 있는데 이렇게 정해주면 해당 origin에 대한 요청만 받는것이기 때문에 이 방식은 괜찮다고 생각한다.
2. 프록시 사용
우선 프록시는 내 요청을 서버의 오리진으로 바꿔서 요청을 보내주는 방식인데
방식은 크게 두가지가 있다.
'내 주소'/api
이렇게 요청을 보내면 포워드 프록시가 '서버주소'/api
이렇게 변환해서 요청을 보내준다.그럼 이 두가지 중에 뭐가더 좋냐
우선 백엔드와 협업이 잘된다면 Origin을 정하는게 제일 좋지 않을까 싶다.
그리고 프록시는 forward보단 reverse가 낫다고 생각한다
그 이유는 뭐 성능은 같겠지만 forward 프록시는 프론트 단에서 어쩃든 서버 주소를 가지고 접근을 하게된다.
하지만 reverse 프록시는 nginx로 예를 들면 프론트단에서 proxy_pass로 설정해 놓은 주소만 정의해 놓으면 되기 때문에 서버의 주소를 숨길수 있다.
따라서 cors를 해결할 때에는 origin 자체를 설정하거나 reverse proxy를 구축해서 해결하고 reverse proxy를 설정할 겨를이 없다 하면 forward proxy로 해결하면 된다가 내 생각이다.
📌 참고로 쿠키 쓰면 withCredential 설정 해야되는데 이 설정을 찾아봐라...
참고: https://developer.mozilla.org/ko/docs/Web/Security/Same-origin_policy
미친 멋쟁이의 글 잘 봤습니다.