Browse Source
Co-authored-by: weekwith.me <[email protected]> Co-authored-by: Sebastiรกn Ramรญrez <[email protected]> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>pull/5851/head
committed by
GitHub
2 changed files with 85 additions and 0 deletions
@ -0,0 +1,84 @@ |
|||
# ๊ต์ฐจ ์ถ์ฒ ๋ฆฌ์์ค ๊ณต์ |
|||
|
|||
<a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS" class="external-link" target="_blank">CORS ๋๋ "๊ต์ฐจ-์ถ์ฒ ๋ฆฌ์์ค ๊ณต์ "</a>๋, ๋ธ๋ผ์ฐ์ ์์ ๋์ํ๋ ํ๋ก ํธ์๋๊ฐ ์๋ฐ์คํฌ๋ฆฝํธ๋ก ์ฝ๋๋ก ๋ฐฑ์๋์ ํต์ ํ๊ณ , ๋ฐฑ์๋๋ ํด๋น ํ๋ก ํธ์๋์ ๋ค๋ฅธ "์ถ์ฒ"์ ์กด์ฌํ๋ ์ํฉ์ ์๋ฏธํฉ๋๋ค. |
|||
|
|||
## ์ถ์ฒ |
|||
|
|||
์ถ์ฒ๋ ํ๋กํ ์ฝ(`http` , `https`), ๋๋ฉ์ธ(`myapp.com`, `localhost`, `localhost.tiangolo.com` ), ๊ทธ๋ฆฌ๊ณ ํฌํธ(`80`, `443`, `8080` )์ ์กฐํฉ์ ์๋ฏธํฉ๋๋ค. |
|||
|
|||
๋ฐ๋ผ์, ์๋๋ ๋ชจ๋ ์์ดํ ์ถ์ฒ์
๋๋ค: |
|||
|
|||
* `http://localhost` |
|||
* `https://localhost` |
|||
* `http://localhost:8080` |
|||
|
|||
๋ชจ๋ `localhost` ์ ์์ง๋ง, ์๋ก ๋ค๋ฅธ ํ๋กํ ์ฝ๊ณผ ํฌํธ๋ฅผ ์ฌ์ฉํ๊ณ ์์ผ๋ฏ๋ก ๋ค๋ฅธ "์ถ์ฒ"์
๋๋ค. |
|||
|
|||
## ๋จ๊ณ |
|||
|
|||
๋ธ๋ผ์ฐ์ ๋ด `http://localhost:8080`์์ ๋์ํ๋ ํ๋ก ํธ์๋๊ฐ ์๊ณ , ์๋ฐ์คํฌ๋ฆฝํธ๋ `http://localhost`๋ฅผ ํตํด ๋ฐฑ์๋์ ํต์ ํ๋ค๊ณ ๊ฐ์ ํด๋ด
์๋ค(ํฌํธ๋ฅผ ๋ช
์ํ์ง ์๋ ๊ฒฝ์ฐ, ๋ธ๋ผ์ฐ์ ๋ `80` ์ ๊ธฐ๋ณธ ํฌํธ๋ก ๊ฐ์ฃผํฉ๋๋ค). |
|||
|
|||
๊ทธ๋ฌ๋ฉด ๋ธ๋ผ์ฐ์ ๋ ๋ฐฑ์๋์ HTTP `OPTIONS` ์์ฒญ์ ๋ณด๋ด๊ณ , ๋ฐฑ์๋์์ ์ด ๋ค๋ฅธ ์ถ์ฒ(`http://localhost:8080`)์์ ํต์ ์ ํ๊ฐํ๋ ์ ์ ํ ํค๋๋ฅผ ๋ณด๋ด๋ฉด, ๋ธ๋ผ์ฐ์ ๋ ํ๋ก ํธ์๋์ ์๋ฐ์คํฌ๋ฆฝํธ๊ฐ ๋ฐฑ์๋์ ์์ฒญ์ ๋ณด๋ผ ์ ์๋๋ก ํฉ๋๋ค. |
|||
|
|||
์ด๋ฅผ ์ํด, ๋ฐฑ์๋๋ "ํ์ฉ๋ ์ถ์ฒ(allowed origins)" ๋ชฉ๋ก์ ๊ฐ์ง๊ณ ์์ด์ผ๋ง ํฉ๋๋ค. |
|||
|
|||
์ด ๊ฒฝ์ฐ, ํ๋ก ํธ์๋๊ฐ ์ ๋๋ก ๋์ํ๊ธฐ ์ํด `http://localhost:8080`์ ๋ชฉ๋ก์ ํฌํจํด์ผ ํฉ๋๋ค. |
|||
|
|||
## ์์ผ๋์นด๋ |
|||
|
|||
๋ชจ๋ ์ถ์ฒ๋ฅผ ํ์ฉํ๊ธฐ ์ํด ๋ชฉ๋ก์ `"*"` ("์์ผ๋์นด๋")๋ก ์ ์ธํ๋ ๊ฒ๋ ๊ฐ๋ฅํฉ๋๋ค. |
|||
|
|||
ํ์ง๋ง ์ด๊ฒ์ ํน์ ํ ์ ํ์ ํต์ ๋ง์ ํ์ฉํ๋ฉฐ, ์ฟ ํค ๋ฐ ์ก์ธ์ค ํ ํฐ๊ณผ ์ฌ์ฉ๋๋ ์ธ์ฆ ํค๋(Authoriztion header) ๋ฑ์ด ํฌํจ๋ ๊ฒฝ์ฐ์ ๊ฐ์ด ์๊ฒฉ ์ฆ๋ช
(credentials)์ด ํฌํจ๋ ํต์ ์ ํ์ฉ๋์ง ์์ต๋๋ค. |
|||
|
|||
๋ฐ๋ผ์ ๋ชจ๋ ์์
์ ์๋ํ๋๋ก ์คํํ๊ธฐ ์ํด, ํ์ฉ๋๋ ์ถ์ฒ๋ฅผ ๋ช
์์ ์ผ๋ก ์ง์ ํ๋ ๊ฒ์ด ์ข์ต๋๋ค. |
|||
|
|||
## `CORSMiddleware` ์ฌ์ฉ |
|||
|
|||
`CORSMiddleware` ์ ์ฌ์ฉํ์ฌ **FastAPI** ์์ฉ ํ๋ก๊ทธ๋จ์ ๊ต์ฐจ ์ถ์ฒ ๋ฆฌ์์ค ๊ณต์ ํ๊ฒฝ์ ์ค์ ํ ์ ์์ต๋๋ค. |
|||
|
|||
* `CORSMiddleware` ์ํฌํธ. |
|||
* ํ์ฉ๋๋ ์ถ์ฒ(๋ฌธ์์ด ํ์)์ ๋ฆฌ์คํธ ์์ฑ. |
|||
* FastAPI ์์ฉ ํ๋ก๊ทธ๋จ์ "๋ฏธ๋ค์จ์ด(middleware)"๋ก ์ถ๊ฐ. |
|||
|
|||
๋ฐฑ์๋์์ ๋ค์์ ์ฌํญ์ ํ์ฉํ ์ง์ ๋ํด ์ค์ ํ ์๋ ์์ต๋๋ค: |
|||
|
|||
* ์๊ฒฉ์ฆ๋ช
(์ธ์ฆ ํค๋, ์ฟ ํค ๋ฑ). |
|||
* ํน์ ํ HTTP ๋ฉ์๋(`POST`, `PUT`) ๋๋ ์์ผ๋์นด๋ `"*"` ๋ฅผ ์ฌ์ฉํ ๋ชจ๋ HTTP ๋ฉ์๋. |
|||
* ํน์ ํ HTTP ํค๋ ๋๋ ์์ผ๋์นด๋ `"*"` ๋ฅผ ์ฌ์ฉํ ๋ชจ๋ HTTP ํค๋. |
|||
|
|||
```Python hl_lines="2 6-11 13-19" |
|||
{!../../../docs_src/cors/tutorial001.py!} |
|||
``` |
|||
|
|||
`CORSMiddleware` ์์ ์ฌ์ฉํ๋ ๊ธฐ๋ณธ ๋งค๊ฐ๋ณ์๋ ์ ํ์ ์ด๋ฏ๋ก, ๋ธ๋ผ์ฐ์ ๊ฐ ๊ต์ฐจ-๋๋ฉ์ธ ์ํฉ์์ ํน์ ํ ์ถ์ฒ, ๋ฉ์๋, ํค๋ ๋ฑ์ ์ฌ์ฉํ ์ ์๋๋ก ํ๋ ค๋ฉด ์ด๋ค์ ๋ช
์์ ์ผ๋ก ํ์ฉํด์ผ ํฉ๋๋ค. |
|||
|
|||
๋ค์์ ์ธ์๋ค์ด ์ง์๋ฉ๋๋ค: |
|||
|
|||
* `allow_origins` - ๊ต์ฐจ-์ถ์ฒ ์์ฒญ์ ๋ณด๋ผ ์ ์๋ ์ถ์ฒ์ ๋ฆฌ์คํธ์
๋๋ค. ์) `['https://example.org', 'https://www.example.org']`. ๋ชจ๋ ์ถ์ฒ๋ฅผ ํ์ฉํ๊ธฐ ์ํด `['*']` ๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค. |
|||
* `allow_origin_regex` - ๊ต์ฐจ-์ถ์ฒ ์์ฒญ์ ๋ณด๋ผ ์ ์๋ ์ถ์ฒ๋ฅผ ์ ๊ทํํ์ ๋ฌธ์์ด๋ก ๋ํ๋
๋๋ค. `'https://.*\.example\.org'`. |
|||
* `allow_methods` - ๊ต์ฐจ-์ถ์ฒ ์์ฒญ์ ํ์ฉํ๋ HTTP ๋ฉ์๋์ ๋ฆฌ์คํธ์
๋๋ค. ๊ธฐ๋ณธ๊ฐ์ `['GET']` ์
๋๋ค. `['*']` ์ ์ฌ์ฉํ์ฌ ๋ชจ๋ ํ์ค ๋ฉ์๋๋ค์ ํ์ฉํ ์ ์์ต๋๋ค. |
|||
* `allow_headers` - ๊ต์ฐจ-์ถ์ฒ๋ฅผ ์ง์ํ๋ HTTP ์์ฒญ ํค๋์ ๋ฆฌ์คํธ์
๋๋ค. ๊ธฐ๋ณธ๊ฐ์ `[]` ์
๋๋ค. ๋ชจ๋ ํค๋๋ค์ ํ์ฉํ๊ธฐ ์ํด `['*']` ๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค. `Accept`, `Accept-Language`, `Content-Language` ๊ทธ๋ฆฌ๊ณ `Content-Type` ํค๋๋ CORS ์์ฒญ์ ์ธ์ ๋ ํ์ฉ๋ฉ๋๋ค. |
|||
* `allow_credentials` - ๊ต์ฐจ-์ถ์ฒ ์์ฒญ์ ์ฟ ํค ์ง์ ์ฌ๋ถ๋ฅผ ์ค์ ํฉ๋๋ค. ๊ธฐ๋ณธ๊ฐ์ `False` ์
๋๋ค. ๋ํ ํด๋น ํญ๋ชฉ์ ํ์ฉํ ๊ฒฝ์ฐ `allow_origins` ๋ `['*']` ๋ก ์ค์ ํ ์ ์์ผ๋ฉฐ, ์ถ์ฒ๋ฅผ ๋ฐ๋์ ํน์ ํด์ผ ํฉ๋๋ค. |
|||
* `expose_headers` - ๋ธ๋ผ์ฐ์ ์ ์ ๊ทผํ ์ ์์ด์ผ ํ๋ ๋ชจ๋ ์๋ต ํค๋๋ฅผ ๊ฐ๋ฆฌํต๋๋ค. ๊ธฐ๋ณธ๊ฐ์ `[]` ์
๋๋ค. |
|||
* `max_age` - ๋ธ๋ผ์ฐ์ ๊ฐ CORS ์๋ต์ ์บ์์ ์ ์ฅํ๋ ์ต๋ ์๊ฐ์ ์ด ๋จ์๋ก ์ค์ ํฉ๋๋ค. ๊ธฐ๋ณธ๊ฐ์ `600` ์
๋๋ค. |
|||
|
|||
๋ฏธ๋ค์จ์ด๋ ๋๊ฐ์ง ํน์ ํ ์ข
๋ฅ์ HTTP ์์ฒญ์ ์๋ตํฉ๋๋ค... |
|||
|
|||
### CORS ์ฌ์ ์์ฒญ |
|||
|
|||
`Origin` ๋ฐ `Access-Control-Request-Method` ํค๋์ ํจ๊ป ์ ์กํ๋ ๋ชจ๋ `OPTIONS` ์์ฒญ์
๋๋ค. |
|||
|
|||
์ด ๊ฒฝ์ฐ ๋ฏธ๋ค์จ์ด๋ ๋ค์ด์ค๋ ์์ฒญ์ ๊ฐ๋ก์ฑ ์ ์ ํ CORS ํค๋์, ์ ๋ณด ์ ๊ณต์ ์ํ `200` ๋๋ `400` ์๋ต์ผ๋ก ์๋ตํฉ๋๋ค. |
|||
|
|||
### ๋จ์ํ ์์ฒญ |
|||
|
|||
`Origin` ํค๋๋ฅผ ๊ฐ์ง ๋ชจ๋ ์์ฒญ. ์ด ๊ฒฝ์ฐ ๋ฏธ๋ค์จ์ด๋ ์์ฒญ์ ์ ์์ ์ผ๋ก ์ ๋ฌํ์ง๋ง, ์ ์ ํ CORS ํค๋๋ฅผ ์๋ต์ ํฌํจ์ํต๋๋ค. |
|||
|
|||
## ๋ ๋ง์ ์ ๋ณด |
|||
|
|||
<abbr title="๊ต์ฐจ-์ถ์ฒ ๋ฆฌ์์ค ๊ณต์ ">CORS</abbr>์ ๋ํ ๋ ๋ง์ ์ ๋ณด๋ฅผ ์๊ณ ์ถ๋ค๋ฉด, <a href="https://developer.mozilla.org/ko/docs/Web/HTTP/CORS" class="external-link" target="_blank">Mozilla CORS ๋ฌธ์</a>๋ฅผ ์ฐธ๊ณ ํ๊ธฐ ๋ฐ๋๋๋ค. |
|||
|
|||
!!! note "๊ธฐ์ ์ ์ธ๋ถ ์ฌํญ" |
|||
`from starlette.middleware.cors import CORSMiddleware` ์ญ์ ์ฌ์ฉํ ์ ์์ต๋๋ค. |
|||
|
|||
**FastAPI**๋ ๊ฐ๋ฐ์์ธ ๋น์ ์ ํธ์๋ฅผ ์ํด `fastapi.middleware` ์์ ๋ช๊ฐ์ง์ ๋ฏธ๋ค์จ์ด๋ฅผ ์ ๊ณตํฉ๋๋ค. ํ์ง๋ง ๋๋ถ๋ถ์ ๋ฏธ๋ค์จ์ด๊ฐ Stralette์ผ๋ก๋ถํฐ ์ง์ ์ ๊ณต๋ฉ๋๋ค. |
Loadingโฆ
Reference in new issue