왜 CORS ?

jaehan·2022년 5월 4일
2

개발지식

목록 보기
1/7
post-thumbnail

항상 개발할때마다 cors를 만나게 되는데 이제는 진짜 cors해결을 다 했다고 생각해서 다시 써본다.


Protocol, Host, Port를 합친걸 출처(Origin)라고 하는데 이 출처중에 하나라도 다르면 출처가 다르다고 판단되고 동일 출처 정책에 위반된다.

동일 출처 정책이란? 👉 동일 출처 정책


💻 CORS란?

교차 출처 리소스 공유(Cross-Origin Resource Sharing).
추가 HTTP 헤더를 사용하여, 한 출처에서 실행 중인 웹 애플리케이션이 다른 출처의 선택한 자원에 접근할 수 있는 권한을 부여하도록 브라우저에 알려주는 체제


💡 CORS의 동작

  1. 기본적으로 웹은 다른 출처의 리소스를 요청할 때는 HTTP 프로토콜을 사용하여 요청을 하는데,
    이때 브라우저는 요청 헤더 (request header)Origin 필드에 요청을 보내는 출처를 담아 전송한다.

  2. 서버는 요청에 대한 응답을 하는데, 응답 헤더 (response header)에 Access-Control-Allow-Origin이라는 값에 '이 리소스를 접근하는 것이 허용된 출처'를 내려준다.
    이후 응답을 받은 브라우저는 자신이 보냈던 요청의 Origin과 서버가 보내준 응답의 Access-Control-Allow-Origin을 비교해 본 후 이 응답이 유효한 응답인지 아닌지를 결정한다.

📌 이것이 기본적인 동작이지만 모든 CORS에서 이렇게 동작하진 않는다


💡 CORS 동작 원리

CORS의 동작 방식은 단순 요청 방법과 예비 요청을 먼저 보내는 방법 2가지 방법이 있다.

Simple Reqeust

Simple Reqeust는 서버에게 바로 요청을 보내는 방법이다.

단순 요청은 서버에 API를 요청하고, 서버는 Access-Control-Allow-Origin 헤더를 포함한 응답을 브라우저에 보냅니다. 브라우저는 Access-Control-Allow-Origin 헤더를 확인해서 CORS 동작을 수행할지 판단한다.

Preflight Request

Preflight Reqeust는 서버에 예비 요청을 보내서 안전한지 판단한 후 본 요청을 보내는 방법이다.

실제 리소스를 요청하기 전에 OPTIONS 메서드로 서버에 예비 요청을 먼저 보내고, 서버는 이 예비 요청에 대한 응답으로 Access-Control-Allow-Origin 헤더를 포함한 응답을 브라우저에 보냅니다. 브라우저는 단순 요청과 동일하게 Access-Control-Allow-Origin 헤더를 확인해서 CORS 동작을 수행할지 판단합니다.

💡 그래서 어떻게 해결하지?

우선 다양한 해결방법이 있다.

  1. 그냥 백엔드에서 origin을 *로 설정해서 모든 요청을 다 받아주게 설정하는 방법
    -> 이건 쿠키를 사용하게 된다면 막힌다...
    -> 또한 서버에서 모든 요청을 받아버리는건 좋지 않은 생각이다.
  2. 아예 맞추면 안되나?
    -> 맨위에 저 origin을 맞추기에는 어려움이 있다

그래서 내가 생각하는 좋은 방식은 2가지이다.

1. 서버에서 origin을 설정해주는것
서버에서 origin 자체를 정해줄 수 가 있는데 이렇게 정해주면 해당 origin에 대한 요청만 받는것이기 때문에 이 방식은 괜찮다고 생각한다.

2. 프록시 사용
우선 프록시는 내 요청을 서버의 오리진으로 바꿔서 요청을 보내주는 방식인데
방식은 크게 두가지가 있다.

  • forward proxy: 포워드 프록시는
    브라우저 - 포워드 프록시 - 인터넷 - 서버
    이렇게 이루어지는 형태이다.
    따라서 브라우저에서 '내 주소'/api 이렇게 요청을 보내면 포워드 프록시가 '서버주소'/api 이렇게 변환해서 요청을 보내준다.
    사용 방법은 webpack proxy, vite proxy, nginx proxy등등 다양한 방식이 있다.
  • reverse proxy: 리버스 프록시는
    브라우저 - 인터넷 - 리버스 프록시 - 서버
    이렇게 이루어지는 형태이다
    동작방식은 위와 같다.
    사용방식은 nginx를 사용하는게 가장 보편적이다 옛날에는 apache?

그럼 이 두가지 중에 뭐가더 좋냐

우선 백엔드와 협업이 잘된다면 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

1개의 댓글

comment-user-thumbnail
2023년 5월 31일

미친 멋쟁이의 글 잘 봤습니다.

답글 달기