본문 바로가기
Fast API/fastapi배우기

Fast API 배우기 22부 - CORS

by 붕어사랑 티스토리 2021. 11. 5.
반응형

CORS란(Cross Origin Resource Sharing)

CORS란 프론트엔드가 백엔드와 소통하는 자바스크립트 코드를 가지고 있는데, 백엔드와 프론트엔드의 Origin이 다를 때 생기는 상황이다.

 

보통 이런상황이면 저 자바스크립트 코드가 실행이 안된다. 그럼 어떻게 해결해야 할까?

 

 

Origin이란?

origin이란 protocol(http, https) + domain(myapp.com, localhost, localhost.tiangolo.com) + port(80,443,8080) 을 의미한다.

 

http://127.0.0.1:8000/

 

요런거

 

가령 모든 프론트엔드 백엔드가 localhost에 있어도, 포트번호가 다르면 다른 Origin이다.

 

 

 

 

자 예시를 들자.

 

당신이 프론트엔드를 http://localhost:8080 에 만들었고, 이 프론트엔드는 백엔드와 소통하는 자바스크립트 코드를 가졌다고 하자.

 

그리고 백엔드 주소는 http://localhost이다.(포트번호를 안적으면 자동으로 80이 된다.)

 

 

그리고 브라우저가 HTTP OPTIONS를 백엔드에 보내고, 백엔드가 다른 Origin(http://localhost:8080, 프론트엔드의 origin)에 통신을 허가하는 적절한 헤더를 보내면, 브라우저는 프론트엔드에 있는 자바스크립트가 백엔드에 리퀘스트를 전송하도록 한다.

 

이것을 하려면 백엔드는 allowed origins 라는 리스트를 가지고 있어야 한다.

위 예시에서 allowed origins는  프론트엔드의 origin이 되어야 할 것이다. http://localhost:8080

 

 

Wildcards

모든 origin을 allowed 하는 방법은 와일드 카드 "*"를 이용하는 것이다.그러나 이런것은 특정 유형의 통신에만 허용하는것이 좋다. Cookie나 Bearer Token 등에 사용되는 authorization header에 말이다.

 

 

 

 

CORSMiddleware

 

위 CORS를 허가 하기위해 fastapi에서는 CORSMiddleware를 사용한다

 

사용법은 다음과 같다.

  • CORSMiddleware를 import한다
  • allowed origins 리스트를 string list로 만든다.
  • 위 사항들을 FastAPI application에 추가한다.

또한 백엔드에 다음과 같은 사항도 추가가 가능하다.

  • Credentials 허락여부(Authorization headers, Cookies, etc)
  • HTTP methods(POST, PUT), 다 허락하려면 와일드카드 "*" 사용
  • 특정 HTTP 헤더, 전부다 허락하려면 화일드카드 "*" 사용

 

from fastapi import FastAPI

from fastapi.middleware.cors import CORSMiddleware


app = FastAPI()


origins = [
    "http://localhost.tiangolo.com",
    "https://localhost.tiangolo.com",
    "http://localhost",
    "http://localhost:8080",
]



app.add_middleware(
    CORSMiddleware,
    allow_origins=origins,
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)



@app.get("/")
async def main():
    return {"message": "Hello World"}

 

코드를 설명하자면

 

허락할 origin 리스트를 만든다.

origins = [
    "http://localhost.tiangolo.com",
    "https://localhost.tiangolo.com",
    "http://localhost",
    "http://localhost:8080",
]

 

앱에다가 미들웨어를 등록해주고 credential이랑 http method, header 허락 여부를 설정한다.

app.add_middleware(
    CORSMiddleware,
    allow_origins=origins,
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)
반응형

 

CORSMiddleware에 사용되는 파라미터들은 보통 default값들이 cross domain에 대해 제한적이 되도록 설정되어있다.

그래서 cross domain의 context를 허락해주려면 파라미터들을 명시적으로 enable 해 주어야 한다.

 

아래는 CORSMiddleware에 사용되는 파라미터들이다.

  • allow_origins - CORS를 허락해줄 origin들의 리스트이다
  • allow_origin_regex - 정규식으로 표현된 origin들이다. e. g. 'https://.*\.example\.org'
  • allow_methods - HTTP 메소드 허락 목록이다. default 값으로 ['GET'] 을 가진다.
  • allow_headers - 허락될 HTTP header 리스트이다.
    여기서 Accept, Accept-Language, Content-Language, Content-Type 헤더들은 CORS 리퀘스트에서
    항상 허락된다.
  • allow_credentials - 쿠키가 CORS 지원이 되는지 나타낸다. 기본값은 False이다. False일경우 allow_origins에 와일드카드("*")를 사용할 수 없다. 반드시 orgin들을 지정해주어야 한다.
  • expose_headers - 브라우저에서 액세스 가능하돌 만들어야 하는 헤더들을 나타낸다. 기본값은 텅빈 리스트 [] 이다.
  • max_age - 브라우저가 CORS응답을 caching할 최대 시간을 설정한다. 기본값은 600초 이다.

 

CORSMiddleware는 아래 두가지 특정유형의 HTTP request에 reponse를 넘겨준다.

 

CORS preflight requests, 사전요청

origin과 access-control-request-mehod 헤더가 있는 OPTION request 이다

 

그냥 한마디로 "백엔드님 CORS 헤도 되쥬?" 하는 request이다.

 

이 경우 middleware가 리퀘스트 가로채고 CORS 헤더와 함께

허락하면 200 OK 거절이면 400으로 응답한다.

 

 

Simple request

Origin Header가 있는 모든 request, 이경우 request는 정상적으로 전달되지만 response에 적절한 CORS헤더가 포함되게 된다.

반응형

댓글