인피니 2023. 7. 16. 15:26

들어가기 전 


최근 회사에서 개발하면서 특정 조건에서 버튼 클릭 시 개발 서버에 올라간 새로운 페이지 url로 이동하도록 구현했는데 페이지가 제대로 뜨지 않은 일이 있었다.

해당 개발팀에 여쭤보니 cors 때문이라고 했다.

cors 는 도메인이 다른 서버로 데이터를 요청할 때 뜨는 것으로 알고 있는데.. 딱 요정도만 알고 있어, 제대로 정리해보자 싶어 쓰는 글 

 

 

CORS


  • Origin 이 다른 서버의 자원을 요청하는 메커니즘이다. (한 서버에서 도메인이 다른 서버로 데이터를 요청하는 것) 
  • 다른 출처 간의 리소스 공유 
  • 출처를 비교하는 로직은 브라우저에 구현되어 있다. 
    • 브라우저에 해당 로직이 구현되어 있기 때문에 브라우저를 거치지 않고, 서버 간 통신을 할 경우 이 정책이 적용되지 않는다.
    • CORS를 위반하는 리소스 요청을 하더라도, 서버에서는 정상응답을 해주고, 이후 브라우저에서 이 응답을 분석해 CORS 정책위반이라고 판단되면 그 응답을 버린다.

CORS 동작원리


  • (Request 의 Origin  헤더의 값) == (Response의 Access Control Allow Origin 헤더의 값) 이면 브라우저에서 같은  출처라고 인식 
    • 즉, 브라우저에서 자신이 보낸 요청의 Origin 과 서버가 보내준 응답의 Access-Controller-Allow-Origin을 비교해 본 후 이 응답이 유효한 응답인지 아닌지를 결정하는 것 
    • Origin에는 요청을 보내는 출처가 담기고, access-controller-allow-origin 에는 이 리소스에 접근하는 것이 허용된 출처가 담김 
    • 기본적인 흐름은 같지만, Cors 가 동작하는 과정은 세 가지 시나리오에 따라 변경되기 때문에 자신의 요청이 어느 시나리오에 해당되는지 파악한다면 CORS 정책 위반으로 인한 에러를 고치는 것이 쉬울 것이다.
  • Preflight Request
    • Preflight Request (사전요청) 은 일반적인 상황에서 브라우저에서 자동으로 발생 
    • 요청을 한 번에 보내지 않고, 예비 요청과 본 요청으로 나누어 서버에 전송
    • 예비요청을 preflight request라고 함, 예비 요청에는 HTTP 메서드의 OPTIONS 메서드가 이용됨 
    • 예비요청의 목적은 본 요청 전 브라우저 스스로 이 서버에 요청을 보내는 것이 안전한 지를 확인하기 위함
    • 브라우저는 자신이 보낸 예비 요청과 서버의 응답에 포함된 허용 정책을 비교한 후. 이 요청을 보내는 것이 안전하다고 판단되면 같은 엔드포인트로 다시 요청을 보낸다.

사진 출처: https://velog.io/@wjdwl002/CORS%EC%9D%98-%EA%B8%B0%EB%B3%B8-%EA%B0%9C%EB%85%90%EA%B3%BC-%EB%8F%99%EC%9E%91-%EB%B0%A9%EC%8B%9D%EB%B6%80%EC%A0%9C-Preflight-%EC%9A%94%EC%B2%AD%EC%9D%B4%EB%9E%80

  • Simple Request 
    • 예비 요청 없이 본 요청만으로, CORS 정책 위반 여부를 따진다.
    • Simple Request는 예비요청을 하지 않는 것으로 예비 요청을 생략할 수 있는 조건이 있다.
      • 만족해야 하는 조건 
        •  요청 메서드는 GET, HEAD, POST 중 하나 
        • Accept, Accept-Language, Content-Language, Content-Type, DPR, Downlink, Save-Data, Viewport-width, Width를 제외한 헤더를 사용하면 안 됨 
        • 만약 Content-Type를 사용하는 경우 application/x-www-form-urlencoded. multipart/form-data, text/plain 만 허용됨 
  • Credential Request 
    • 인증된 요청을 사용하는 방법 
    • 기본적으로 브라우저에는 별도의 옵션 없이 쿠키 정보나 인증과 관련된 헤더를 요청에 함지 않는다. 쿠키나 인증 관련 정보를 넣을 수 있도록 하는 방법이 Credential 옵션을 사용하는 것이다.
    • Credential 값이 include 일 경우, Access-Control-Allow-Origin에 *(모든 요청을 허용한다는 의미)를 넣을 수 없게 된다. 
    • Credential 옵션에는 3가지 값을 사용할 수 있으며, 각 값들이 가지는 의미는 다음과 같다.
옵션값  설명
same-origin (기본값) 같은 출처 간 요청에만 인증 정보를 담을 수 있다.
include 모든 요청에 인증 정보를 담을 수 있다.
omit 모든 요청에 인증 정보를 담지 않는다.
  • Credential 옵션에 same-origin or include를 넣어 인증 정보를 전달하는 상황이라면, Access-Control-Allow-Origin 만 확인하는 것이 아닌 인증 관련 정보를 같이 검사하기 때문에 좀 더 빡빡한 검사조건을 갖게 된다.

 

 

출처