본문 바로가기
Computer Science/Network

개발자를 화나게 하는 슈슈규슈ㅠ슈규슉... CORS 😡

by HelloJudy 2022. 6. 25.

python server와 node server를 프론트에게 넘기고 평화롭게 한숨을 돌리던 그때..

 

뜨헉..

 

 

그것이 왔다.. CORS..! 🤦‍♀️

 

 

🥺 FE: 정윤님..! CORS 에러요..!!

🥲 BE (나): 네엥 ㅠㅠ 잠시만용!!!

 

 

나를 화나게 하는 CORS는 대체 어떤거일까!? 어떻게 해결할 수 있을까!

지금부터 알아보자! 🤔

 

 


 

✔️ SOP (Same Origin Policy)

 

다른 출처의 리소스를 사용하는 것에 제한하는 보안 방식.

 

SOP로 다른 출처의 리소스를 제한한다면..!

다른 출처의 리소스를 가져와야할 때는 어떻게 해야할까?

.

.

.

CORS 이다!!! 

 


 

1. CORS 란

Cross-Origin Resource Sharing, 다른 출처의 자원을 공유하는 것

 

✔️ CORS 접근제어 시나리오

1️⃣ 단순 요청 (Simple Request)

 

프리플라이트 요청과 다르게 바로 본 요청을 보내며 즉시 cross origin인지 확인 한다.

 

But..!!! 3가지의 조건을 만족해야한다.

 

  1. GET, POST, HEAD 메서드 중 하나.
  2. Content-Type은 application/x-www-form-urlencoded , multipart/form-data , text/plain 중 하나.
  3. Header는 Accept, Accept-Language, Content-Language, Content-Type 만 허용

 

 

 

 

 

2️⃣ 프리플라이트 요청 (Preflight Request)

쉽게 말하면 '사전 작업' 이다.

 

OPTIONS 메서드를 통해 다른 도메인의 리소스 요청이 가능한지 확인한다.

그리고 가능하면 실제 요청(Actual Request)를 보낸다

 

즉, 요청을 보내기 전에 요청이 가능한 지 확인하는 작업을 말한다.

 

 

[ Preflight ]

 

 

 

[ Request ]

  • Origin : 요청 출처
  • Access-Control-Request-Method : 실제 요청의 메서드  ex) POST
  • Access-Control-Request-Headers : 실제 요청의 추가 헤더

[ Response ]

  • Access-Control-Allow-Origin : 서버 측 허가 출처
  • Access-Control-Allow-Method : 서버 측 허가 메서드
  • Access-Control-Allow-Headers : 서버 측 허가 헤더
  • Access-Control-Max-Age: Preflight : 응답 캐시 기간
    • 요청을 두 번 보낸다는건 효율적이지 않기 때문에 캐시를 해둔다.

 

 

[ 왜 Preflight가 필요할까 ]

 

CORS를 모르는 서버를 위해서!

 

 

 

3️⃣ 인증정보 포함 요청 (Credentialed Request)

인증 관련 헤더를 포함(쿠키, jwt)할 때 사용하는 요청


👩‍💻클라이언트: 쿠키, jwt 등을 클라이언트에서 자동으로 담아서 서버에 보내고 싶을 때 credentials를 포함시킨다.

 

👨‍💻서버: Access-Control-Allow-Credentials 를 true로 넣어준다.

    (모든 출처를 허용하면 안된다. 즉, Access-Control-Allow-Credentials : * 을 하면 안된다.)

 

 

 

 

2. CORS 해결하자!

 

1️⃣ 프론트 프록시 서버 설정 (개발환경)

 

 

2️⃣ 직접 헤더에 설정

 

 

3️⃣ 스프링 부트를 이용

 


 

파이썬 서버에서 생긴 CORS는 다음 방식을 이용해서 해결할 수 있었다.

 

 

* app.py

CORS(app)
CORS(app, resources={r'': {'origins': ''}}, expose_headers=["Content-disposition"])

 


📌 Reference

반응형

댓글