๐ ์๋ก
- [์ฃผ์ ์๊ฐ]: ์ค๋ ๋ค๋ฃฐ ์ฃผ์ ๋ ๋ฐ๋ก ์น ๊ฐ๋ฐ๊ณผ ์ด์์ ํ์ ์์์ธย Nginx CORS(Cross-Origin Resource Sharing) ์ ์ฑ ์ ๋๋ค. ์น ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ฐ๋ฐํ๊ณ ๋ฐฐํฌํ๋ ๊ณผ์ ์์ "CORS ์ค๋ฅ"๋ผ๋ ๋นจ๊ฐ ๊ธ์จ๋ฅผ ํ ๋ฒ์ฏค์ ๋ง์ฃผ์น์ จ์ ํ ๋ฐ์. ์ด CORS๊ฐ ๋ฌด์์ธ์ง, Nginx์์ ์ด๋ป๊ฒ ์ค์ ํ๊ณ , ์ ์ ๋๋ก ๊ด๋ฆฌํด์ผ ํ๋์ง ๊ทธ ์ค์์ฑ์ ๊น์ด ํํค์ณ ๋ณด๊ฒ ์ต๋๋ค. ๋จ์ํ ์ค๋ฅ๋ฅผ ํด๊ฒฐํ๋ ๊ฒ์ ๋์ด, ๋ณด์๊ณผ ์์ ์ฑ์ ๋์์ ์ก๋ ์ค์ ๋ ธํ์ฐ๋ฅผ ๊ณต์ ํด ๋๋ฆด ๊ฒ์ ๋๋ค.
- [์ ์์ฑํ์๋๊ฐ? ]: ์ด ๊ธ์ ๋จ์ํ CORS ์๋ฌ๋ฅผ ์์ ๋ ์์๋ฐฉํธ์ด ์๋, ๊ทผ๋ณธ์ ์ธ ์ดํด์ ์ค๋ฌด์์ ๋ฐ์ํ ์ ์๋ ์ ์ฌ์ ์ํ์ ํํผํ๊ณ ๋ ๋์๊ฐ ์์คํ ์ ๋ณด์ ์์ค์ ํ ๋จ๊ณ ๋์ด์ฌ๋ฆด ์ ์๋ ํต์ฐฐ๋ ฅ์ ์ ๊ณตํ๊ณ ์ ์์ฑ๋์์ต๋๋ค. ๋ ์ ์ฌ๋ฌ๋ถ์ ์ด ๊ธ์ ํตํด Nginx CORS ์ ์ฑ ์ ์๋ฒฝํ๊ฒ ๋ง์คํฐํ๊ณ , ๋ณต์กํ ์น ํ๊ฒฝ์์๋ ์ ์ฐํ๊ณ ์์ ํ๊ฒ ์๋น์ค๋ฅผ ์ด์ํ๋ ๋ฐ ํ์ํ ์ง์๊ณผ ์ค์ ํ์ ์ป์ด๊ฐ์ค ์ ์์ ๊ฒ์ ๋๋ค.
๐ Nginx CORS ์ ์ฑ : ํต์ฌ ๊ฐ๋ ํํค์น๊ธฐ
- [CORS (Cross-Origin Resource Sharing)]: ๐ ์น ์ ํ๋ฆฌ์ผ์ด์ ์ด ๋ค๋ฅธย Origin(์ถ์ฒ)์ ๋ฆฌ์์ค์ ์ ๊ทผํ ์ ์๋๋ก ํ์ฉํ๋ ๋ฉ์ปค๋์ฆ์ ๋๋ค. Origin์ ํ๋กํ ์ฝ(http/https), ๋๋ฉ์ธ(www.example.com), ํฌํธ(80/443/8080)์ ์กฐํฉ์ผ๋ก ๊ฒฐ์ ๋ฉ๋๋ค. ์ด ์ค ํ๋๋ผ๋ ๋ค๋ฅด๋ฉด "๋ค๋ฅธ Origin"์ผ๋ก ๊ฐ์ฃผ๋ฉ๋๋ค.
- ์ ์ค์ํ๊ฐ์?: ํ๋ ์น์ ์๋ง์ ์๋น์ค์ API๊ฐ ์๋ก ์ฐ๋๋๋ ๋ณต์กํ ๊ตฌ์กฐ๋ฅผ ๊ฐ์ง๊ณ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด,ย
frontend.com
์ ์น ํ์ด์ง์์ยapi.backend.com
์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๊ฑฐ๋, ๋ค๋ฅธ CDN์์ ์ด๋ฏธ์ง๋ฅผ ๋ก๋ํ๋ ๊ฒฝ์ฐ ๋ฑ ๋ค๋ฅธ Origin ๊ฐ์ ํต์ ์ด ๋น๋ฒํ๊ฒ ๋ฐ์ํฉ๋๋ค. CORS๋ ์ด๋ฌํ ๊ต์ฐจ Origin ํต์ ์ ์์ ํ๊ฒ ํ์ฉํ๊ธฐ ์ํ ํ์คํ๋ ๋ฐฉ๋ฒ์ ๋๋ค. - [๋์ผ ์ถ์ฒ ์ ์ฑ
(Same-Origin Policy - SOP)]: ๐ก๏ธ ์น ๋ธ๋ผ์ฐ์ ๊ฐ ํน์ Origin์์ ๋ก๋๋ ๋ฌธ์๋ ์คํฌ๋ฆฝํธ๊ฐ ๋ค๋ฅธ Origin์ ๋ฆฌ์์ค์ ์ํธ ์์ฉํ๋ ๊ฒ์ ์ ํํ๋ ๊ทผ๋ณธ์ ์ธ ๋ณด์ ์์น์
๋๋ค.ย
evil.com
์ดยyourbank.com
์ ๋ฏผ๊ฐํ ์ ๋ณด๋ฅผ ๋ชฐ๋ ์ฝ์ด๊ฐ๋ ๊ฒ์ ๋ง๋ ๋ฐฉํจ์ ๊ฐ์ต๋๋ค. - ๋์น๊ธฐ ์ฌ์ด ์ : ๋ง์ ๊ฐ๋ฐ์๊ฐ CORS ์ค๋ฅ๋ฅผ ๋ง๋๋ฉด ๋จ์ํ "๋ธ๋ผ์ฐ์ ๊ฐ ๋ง๊ณ ์๊ตฌ๋"๋ผ๊ณ ๋ง ์๊ฐํ๊ณ SOP์ ๊ทผ๋ณธ์ ์ธ ๋ณด์ ์ค์์ฑ์ ๊ฐ๊ณผํ๊ณค ํฉ๋๋ค. SOP๋ ์ฌ์ฉ์ ์ ๋ณด ๋ณดํธ์ ์ฒซ ๋ฒ์งธ ๋ฐฉ์ด์ ์ด๋ฉฐ, CORS๋ ์ด ๋ฐฉ์ด์ ์ ํฉ๋ฒ์ ์ผ๋ก ํต๊ณผํ ์ ์๋ ์ ์ผํ ํต๋ก์
๋๋ค.ย
Access-Control-Allow-Origin: *
์ ๋ฌด์ฌ์ฝ ์ฌ์ฉํ๋ฉด ์ด ์ค์ํ ๋ฐฉ์ด์ ์ ๋ฌด๋ ฅํ์ํค๋ ๊ฒ๊ณผ ๊ฐ์ต๋๋ค. - [Access-Control-Allow-Origin ํค๋]: ๐ ์๋ฒ๊ฐ ํด๋ผ์ด์ธํธ์๊ฒ "์ด ๋ฆฌ์์ค๋ ํน์ Origin์์๋ง ์ ๊ทผํ ์ ์์ด" ๋๋ "์ด ๋ฆฌ์์ค๋ ๋ชจ๋ Origin์์ ์ ๊ทผํ ์ ์์ด"๋ผ๊ณ ์๋ ค์ฃผ๋ HTTP ์๋ต ํค๋์ ๋๋ค.
- ์ค๋ฌด ์ ์ฉ ์ ๊ณ ๋ ค์ฌํญ:
*
ย (์์ผ๋์นด๋): ๋ชจ๋ Origin์ ํ์ฉํฉ๋๋ค. ๋ณด์์ ๊ฐ์ฅ ์ทจ์ฝํ๋ฉฐ, ๋ฏผ๊ฐํ ์ ๋ณด๋ฅผ ๋ค๋ฃจ๋ API์์๋ ์ ๋ ์ฌ์ฉํด์๋ ์ ๋ฉ๋๋ค.https://www.example.com
: ํน์ ๋จ์ผ Origin๋ง ํ์ฉํฉ๋๋ค. ๊ฐ์ฅ ์์ ํ ๋ฐฉ์์ ๋๋ค.https://sub.example.com, https://another.example.com
: ์ฌ๋ฌ Origin์ ํ์ฉํด์ผ ํ ๊ฒฝ์ฐ, Nginx์์๋ ์ฌ๋ฌยadd_header
ย ์ง์๋ฌธ์ ์ฌ์ฉํ์ฌ ๊ฐ๋ณ์ ์ผ๋ก ์ค์ ํ๊ฑฐ๋,ย$http_origin
ย ๋ณ์๋ฅผ ํ์ฉํ์ฌ ๋์ ์ผ๋ก ์ฒ๋ฆฌํด์ผ ํฉ๋๋ค.
๐ Nginx CORS ์ ์ฑ : ๊ณต์ ๊ฐ์ด๋๋ผ์ธ & ๊ถ์ฅ ์ฌํญ
- [๊ณต์ ์์ค]: Nginx ๊ณต์ ๋ฌธ์ (nginx.org/en/docs/http/ngx_http_headers_module.html#add_header) ๋ฐ Mozilla ๊ฐ๋ฐ์ ๋คํธ์ํฌ(MDN)์ CORS ๋ฌธ์(developer.mozilla.org/ko/docs/Web/HTTP/CORS)๋ฅผ ์ฐธ๊ณ ํ๋ ๊ฒ์ด ๊ฐ์ฅ ์ ํํ๊ณ ์ ๋ขฐํ ์ ์์ต๋๋ค.
- [์ฃผ์ ๊ถ์ฅ ์ฌํญ]:
- ์์ ์ ์ผ ์์น: ๐จย
Access-Control-Allow-Origin: *
ย ์ฌ์ฉ์ ๊ทน๋๋ก ์์ ํด์ผ ํฉ๋๋ค. ํนํ ๋ก๊ทธ์ธ ์ ๋ณด, ๊ฐ์ธ ๋ฐ์ดํฐ, ๊ฒฐ์ ์ ๋ณด ๋ฑ ๋ฏผ๊ฐํ ๋ฐ์ดํฐ๋ฅผ ์ฒ๋ฆฌํ๋ API์์๋ ์ ๋ ๊ธ์ง์ ๋๋ค. ํ์ฉํด์ผ ํ Origin์ ๋ช ํํ ์ง์ ํ์ฌ ์ต์ ๊ถํ์ ์์น์ ์งํค์ธ์. - ํน์ Origin ๋ช
์: ๐ฏ ๊ฐ๋ฅํ ํ ํน์ Origin(์:ย
https://your-frontend.com
)๋ง ํ์ฉํ๋๋ก ์ค์ ํฉ๋๋ค. ์ฌ๋ฌ Origin์ ํ์ฉํด์ผ ํ๋ค๋ฉด, ๊ฐ Origin์ ๋ช ์์ ์ผ๋ก ์ถ๊ฐํ๊ฑฐ๋ย$http_origin
ย ๋ณ์๋ฅผ ํ์ฉํ ์กฐ๊ฑด๋ถ ์ค์ ์ ๊ณ ๋ คํ์ธ์. OPTIONS
ย ๋ฉ์๋ ์ฒ๋ฆฌ: โ๏ธ Preflight ์์ฒญ(์ฌ์ ์์ฒญ)์ ์ฒ๋ฆฌํ๊ธฐ ์ํดยOPTIONS
ย HTTP ๋ฉ์๋์ ๋ํ ์ ์ ํ ์๋ต์ ๊ตฌ์ฑํด์ผ ํฉ๋๋ค. ์ด๋ ํด๋ผ์ด์ธํธ๊ฐ ์ค์ ์์ฒญ์ ๋ณด๋ด๊ธฐ ์ ์ ์๋ฒ๊ฐ CORS๋ฅผ ํ์ฉํ๋์ง ํ์ธํ๋ ๊ณผ์ ์ ๋๋ค.Access-Control-Allow-Credentials
ย ์ฃผ์: ๐ช ์ฟ ํค๋ HTTP ์ธ์ฆ๊ณผ ๊ฐ์ ์๊ฒฉ ์ฆ๋ช ์ ํ์ฉํ๋ยAccess-Control-Allow-Credentials: true
ย ํค๋๋ยAccess-Control-Allow-Origin: *
์ ํจ๊ป ์ฌ์ฉํ ์ ์์ต๋๋ค. ์ด ๊ฒฝ์ฐ ๋ธ๋ผ์ฐ์ ๊ฐ ์ค๋ฅ๋ฅผ ๋ฐ์์ํต๋๋ค. ์๊ฒฉ ์ฆ๋ช ์ด ํ์ํ ๊ฒฝ์ฐ ๋ฐ๋์ ํน์ Origin์ ๋ช ์ํด์ผ ํฉ๋๋ค.- ์บ์ฑ ์ ๋ต ๊ณ ๋ ค: ๐จ CORS ํค๋๋ ์บ์ฑ๋ ์ ์์ต๋๋ค.ย
Vary: Origin
ย ํค๋๋ฅผ ์ถ๊ฐํ์ฌ Origin์ ๋ฐ๋ผ ์บ์ฑ๋๋๋ก ์ค์ ํ๋ฉด, ๋ค๋ฅธ Origin์ ํด๋ผ์ด์ธํธ๊ฐ ์๋ชป๋ ์บ์๋ ์๋ต์ ๋ฐ์ง ์๋๋ก ํ ์ ์์ต๋๋ค.
๐ ๏ธ Nginx CORS ์ ์ฑ : ์ค๋ฌด ์ ์ฉ ๋ง์คํฐ ํ๋
CORS ์ ์ฑ ์ Nginx์ ์์ ํ๊ฒ ์ ์ฉํ๋ ๋จ๊ณ๋ณ ๊ฐ์ด๋์ ๋๋ค.
- [์ฒซ ๋ฒ์งธ ๋จ๊ณ: ํ์ฌ CORS ์๊ตฌ์ฌํญ ๋ถ์]
- ๋ฌด์์ ํ๋๊ฐ?: ํ์ฌ ์๋น์ค ์ค์ธ ํ๋ก ํธ์๋ ์ ํ๋ฆฌ์ผ์ด์ (SPA, ๋ชจ๋ฐ์ผ ์ฑ ๋ฑ)์ด ์ด๋ค ๋ฐฑ์๋ API๋ฅผ ํธ์ถํ๋ฉฐ, ๊ฐ API์ ๋ํด ์ด๋ค Origin์์ ์ ๊ทผํด์ผ ํ๋์ง ๋ช ํํ๊ฒ ํ์ ํฉ๋๋ค.
- ์ด๋ป๊ฒ ํ๋๊ฐ?:
- ํ๋ก ํธ์๋ ๊ฐ๋ฐํ๊ณผ ํ์ํ์ฌ ์๋น์ค์ ํ์ํ ์ ํํ Origin ๋ชฉ๋ก์ ํ์ธํฉ๋๋ค.
- ๊ฐ API ์๋ํฌ์ธํธ๊ฐ ๋ฏผ๊ฐํ ์ ๋ณด๋ฅผ ๋ค๋ฃจ๋์ง, ์๊ฒฉ ์ฆ๋ช (์ฟ ํค, ํ ํฐ ๋ฑ)์ ํ์๋ก ํ๋์ง ์๋ณํฉ๋๋ค.
# ์์: ์๊ตฌ์ฌํญ ์ ์ (๊ฐ์์ ์๋๋ฆฌ์ค) # Before # ํ์ฌ Nginx ์ค์ ์ Access-Control-Allow-Origin: * ์ด ์ ์ญ์ผ๋ก ์ ์ฉ๋์ด ์๋ค. # ์ด๋ก ์ธํด ๋ถํ์ํ๊ฒ ๋ชจ๋ Origin์์ ์ ๊ทผ์ด ํ์ฉ๋๊ณ ์๋ค. # After # - ๋ฉ์ธ ์๋น์ค ํ๋ก ํธ์๋: https://app.example.com # - ๊ด๋ฆฌ์ ํ์ด์ง ํ๋ก ํธ์๋: https://admin.example.com # - ๋ชจ๋ฐ์ผ ์ฑ (์น๋ทฐ): CORS๋ ์๋์ง๋ง, ๋์ผ Origin ์ ์ฑ ์ ์ํ ๊ณ ๋ ค ํ์ (์: ๋ธ๋ฆฟ์ง) # - API Gateway: https://api.example.com (๋ฐฑ์๋ ์๋น์ค) # - ์๊ตฌ์ฌํญ: /api/v1/* ๊ฒฝ๋ก์๋ https://app.example.com ๊ณผ https://admin.example.com ๋ง ํ์ฉํด์ผ ํ๋ฉฐ, ์๊ฒฉ ์ฆ๋ช (์ฟ ํค)์ ํฌํจํด์ผ ํ๋ค. # ๋ฌด์์ด ์ด๋ป๊ฒ ๋ณํ๋์ง ์์ฝ # ๊ธฐ์กด์ ๊ด๋ฒ์ํ CORS ํ์ฉ ์ ์ฑ ์์ ํ์ํ Origin๋ง ๋ช ํํ ์ง์ ํ์ฌ ๋ณด์์ ๊ฐํํ๊ณ , ๊ฐ ์๋น์ค์ ํน์ฑ์ ๋ง๋ CORS ์ค์ ์ ์ค๋นํ๋ค.
- ์ฑ๊ณต ์ ๊ฒ: ๋ชจ๋ ํ๋ก ํธ์๋ ์๋น์ค์ URL๊ณผ ํด๋น ์๋น์ค๊ฐ ํธ์ถํ๋ ๋ฐฑ์๋ API์ URL ๋ชฉ๋ก, ๊ทธ๋ฆฌ๊ณ ์๊ฒฉ ์ฆ๋ช ์๊ตฌ ์ฌ๋ถ๊ฐ ๋ช ํํ ์ ์๋ ๋ฌธ์(์: Confluence, Notion)๊ฐ ์ค๋น๋์๋์ง ํ์ธํฉ๋๋ค.
- ์ค์ ๋ฐฉ์ง ํ: โ ๏ธ ๊ฐ๋ฐ์๋ง๋ค ๋ค๋ฅธ Origin์ ์ด์ผ๊ธฐํ ์ ์์ผ๋ฏ๋ก, ์ต์ข
์ ์ผ๋ก ์๋น์ค์ ๋ฐฐํฌ๋ Origin์ ๊ธฐ์ค์ผ๋ก ์ผ์์ผ ํฉ๋๋ค. ๋ก์ปฌ ๊ฐ๋ฐ ํ๊ฒฝ(์:ย
http://localhost:3000
)์ ์ค์ ์ด์ ํ๊ฒฝ๊ณผ ๋ค๋ฅผ ์ ์์ผ๋ฏ๋ก, ์ด์ ํ๊ฒฝ Origin์ ์ต์ฐ์ ์ผ๋ก ๊ณ ๋ คํ์ธ์.
- [๋ ๋ฒ์งธ ๋จ๊ณ: Nginx ์ค์ ํ์ผ ์์ - ํน์ Origin ํ์ฉ]
- ๋ฌด์์ ํ๋๊ฐ?: ๋ถ์๋ ์๊ตฌ์ฌํญ์ ๋ฐํ์ผ๋กย
nginx.conf
ย ๋๋ ํด๋น ์๋น์ค์ยserver
ย ๋ธ๋ก ์ค์ ํ์ผ์ CORS ํค๋๋ฅผ ์ถ๊ฐํฉ๋๋ค. - ์ด๋ป๊ฒ ํ๋๊ฐ?:ย
location
ย ๋ธ๋ก ๋ด์์ยadd_header
ย ์ง์๋ฌธ์ ์ฌ์ฉํ์ฌ ํน์ Origin์ ํ์ฉํ๊ณ ยOPTIONS
ย ์์ฒญ์ ์ฒ๋ฆฌํฉ๋๋ค.
# ์์ ์ฝ๋ ๋๋ ๋ช ๋ น์ด # Before # http { # add_header 'Access-Control-Allow-Origin' '*'; # ์ ์ญ ์์ผ๋์นด๋ CORS (์ด์ ๋ ์ฃผ์ ์ฒ๋ฆฌ๋จ) # ... # } # server { # server_name api.example.com; # location /api/v1/ { # # CORS ์ค์ ์์ (์ด์ ์๋ http ๋ธ๋ก์ *๊ฐ ์ ์ฉ๋์์) # proxy_pass http://backend_service; # ... # } # } # After (nginx/sites-available/api.example.com.conf ํ์ผ์ ์ถ๊ฐ) # server { # listen 443 ssl http2; # server_name api.example.com; # ... # # Preflight ์์ฒญ (OPTIONS ๋ฉ์๋) ์ฒ๋ฆฌ # location /api/v1/ { # if ($request_method = 'OPTIONS') { # add_header 'Access-Control-Allow-Origin' 'https://app.example.com'; # add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS'; # add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,X-CSRFToken'; # add_header 'Access-Control-Max-Age' 1728000; # 20์ผ๊ฐ Preflight ๊ฒฐ๊ณผ ์บ์ฑ # add_header 'Content-Type' 'text/plain; charset=utf-8'; # add_header 'Content-Length' 0; # return 204; # } # # ์ค์ ์์ฒญ ์ฒ๋ฆฌ (GET, POST ๋ฑ) # add_header 'Access-Control-Allow-Origin' 'https://app.example.com'; # add_header 'Access-Control-Allow-Credentials' 'true'; # ์๊ฒฉ ์ฆ๋ช ํ์ฉ (์ค์!) # add_header 'Vary' 'Origin'; # Origin์ ๋ฐ๋ผ ์บ์๊ฐ ๋ค๋ฅด๊ฒ ๋์ํ๋๋ก ์ค์ # proxy_pass http://backend_service; # ... # } # } # ๋ฌด์์ด ์ด๋ป๊ฒ ๋ณํ๋์ง ์์ฝ # ํน์ location ๋ธ๋ก์ ๋ํด ํ์ํ Origin๋ง ๋ช ์์ ์ผ๋ก ํ์ฉํ๊ณ , Preflight ์์ฒญ์ ์ฒ๋ฆฌํ๊ธฐ ์ํ OPTIONS ๋ฉ์๋ ์๋ต์ ์ถ๊ฐํ๋ค. # ์๊ฒฉ ์ฆ๋ช (์ฟ ํค)์ด ํ์ํ ๊ฒฝ์ฐ Access-Control-Allow-Credentials: true๋ฅผ ์ถ๊ฐํ๊ณ , ์ด์ ๋ง์ถฐ Access-Control-Allow-Origin์ ์์ผ๋์นด๋๋ฅผ ์ฌ์ฉํ์ง ์๊ณ ํน์ Origin์ ๋ช ์ํ๋ค.
- ์ฑ๊ณต ์ ๊ฒ:
add_header
ย ์ง์๋ฌธ์ด ์ฌ๋ฐ๋ฅธยlocation
ย ๋๋ยserver
ย ๋ธ๋ก์ ์ถ๊ฐ๋์๋์ง ํ์ธํฉ๋๋ค.Access-Control-Allow-Origin
์ด ํ์ํ Origin๋ง ํฌํจํ๋์ง ํ์ธํฉ๋๋ค.OPTIONS
ย ๋ฉ์๋์ ๋ํ ์ฒ๋ฆฌ๊ฐ ํฌํจ๋์๋์ง ํ์ธํฉ๋๋ค.- ์๊ฒฉ ์ฆ๋ช
์ด ํ์ํ ๊ฒฝ์ฐย
Access-Control-Allow-Credentials: true
๊ฐ ์ฌ๋ฐ๋ฅด๊ฒ ์ค์ ๋์๊ณ ,ยAccess-Control-Allow-Origin
์ด ์์ผ๋์นด๋๊ฐ ์๋ ํน์ Origin์ผ๋ก ์ง์ ๋์๋์ง ์ฌํ์ธํฉ๋๋ค. - ์ค์ ๋ฐฉ์ง ํ: ๐ก ์ฌ๋ฌ Origin์ ํ์ฉํด์ผ ํ ๊ฒฝ์ฐ, ์ ์์์ฒ๋ผ ๋จ์ผย
add_header
์ ์ผํ๋ก ๊ตฌ๋ถํ์ฌ ์ฌ๋ฌ Origin์ ๋์ดํ๋ ๊ฒ์ Nginx์์ ์๋ํ์ง ์์ต๋๋ค. ๋์ ,ยmap
ย ๋ชจ๋์ ์ฌ์ฉํ๊ฑฐ๋ยif
ย ๋ฌธ์ ํ์ฉํ์ฌย$http_origin
ย ๋ณ์์ ๋น๊ตํ ํ ์กฐ๊ฑด๋ถ๋กยadd_header
๋ฅผ ์ถ๊ฐํ๋ ๋ฐฉ์์ ๊ณ ๋ คํด์ผ ํฉ๋๋ค.
- [์ธ ๋ฒ์งธ ๋จ๊ณ: Nginx ์ค์ ์ ํจ์ฑ ๊ฒ์ฌ ๋ฐ ์ฌ์์]
- ๋ฌด์์ ํ๋๊ฐ?: ๋ณ๊ฒฝ๋ Nginx ์ค์ ํ์ผ์ ๋ฌธ๋ฒ์ ์ค๋ฅ๊ฐ ์๋์ง ํ์ธํ๊ณ , ์๋น์ค๋ฅผ ์ฌ์์ํ์ฌ ๋ณ๊ฒฝ ์ฌํญ์ ์ ์ฉํฉ๋๋ค.
- ์ด๋ป๊ฒ ํ๋๊ฐ?: ํฐ๋ฏธ๋์์ Nginx ๋ช
๋ น์ด(
nginx -t
,ยsystemctl restart nginx
)๋ฅผ ์ฌ์ฉํฉ๋๋ค.
# ์์ ์ฝ๋ ๋๋ ๋ช ๋ น์ด # Nginx ์ค์ ํ์ผ ์ ํจ์ฑ ๊ฒ์ฌ sudo nginx -t # Nginx ์๋น์ค ์ฌ์์ sudo systemctl restart nginx
- ์ฑ๊ณต ์ ๊ฒ:ย
nginx -t
ย ๋ช ๋ น ์คํ ์ยsyntax is ok
์ยtest is successful
ย ๋ฉ์์ง๊ฐ ์ถ๋ ฅ๋๋์ง ํ์ธํฉ๋๋ค.ยsystemctl restart nginx
ย ์ดํ, ์๋น์ค์ ์ ์ํ์ฌ ๋ธ๋ผ์ฐ์ ๊ฐ๋ฐ์ ๋๊ตฌ(F12)์ '๋คํธ์ํฌ' ํญ์์ ์ค์ ์์ฒญ ํค๋์ CORS ๊ด๋ จ ํค๋๊ฐ ์ฌ๋ฐ๋ฅด๊ฒ ํฌํจ๋์ด ์๋์ง ํ์ธํฉ๋๋ค. - ์ค์ ๋ฐฉ์ง ํ: โกย
nginx -s reload
๋ ์ค์ ํ์ผ์ ๋ค์ ๋ก๋ํ๋ ๊ฒ์ด์ง๋ง,ยworker_processes
๋ยlisten
ย ์ง์๋ฌธ ๊ฐ์ ์ผ๋ถ ์ค์ ์ยrestart
ย ํด์ผ๋ง ์ ์ฉ๋ฉ๋๋ค. ์์ ์ ์ํดยrestart
๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ ๊ถ์ฅํฉ๋๋ค. ์ค๋ฅ ๋ฐ์ ์ยjournalctl -xe
ย ๋ช ๋ น์ผ๋ก ์์คํ ๋ก๊ทธ๋ฅผ ํ์ธํ์ฌ ๋ฌธ์ ์ ์์ธ์ ํ์ ํ์ธ์.
๐ Nginx CORS ์ ์ฑ : ์์ํ ์ฑ๊ณต & ์คํจ ์ฌ๋ก ๋ถ์
- [์ฑ๊ณต ์ฌ๋ก: ์์ ํ ๋ง์ดํฌ๋ก์๋น์ค ์ฐ๋ ๊ตฌ์ถ]
- ๋ฐฐ๊ฒฝ: ๊ธฐ์กด ๋ ๊ฑฐ์ ์์คํ
์ ๋ง์ดํฌ๋ก์๋น์ค ์ํคํ
์ฒ๋ก ์ ํํ๋ฉฐ, ๋ฐฑ์๋ API๋ย
api.legacy.com
, ์๋ก์ด ํ๋ก ํธ์๋ ์๋น์ค๋ยapp.newservice.com
์ ๋ฐฐํฌ๋์์ต๋๋ค. ์ด๊ธฐ์๋ CORS ๋ฌธ์ ๊ฐ ๋ฐ์ํ์ผ๋, Nginx๋ฅผ ํตํด ์์ ํ๊ฒ ํด๊ฒฐํ๊ณ ์ ํ์ต๋๋ค. - ์ ์ฉ ์ ๋ต: Nginx API Gateway์์ ๊ฐ ๋ง์ดํฌ๋ก์๋น์ค์ย
location
ย ๋ธ๋ก์ยAccess-Control-Allow-Origin
์ ๋ช ์์ ์ผ๋ก ์ค์ ํ์ต๋๋ค. ํนํ, ์ฌ์ฉ์ ์ธ์ฆ์ด ํ์ํยauth
ย ์๋น์ค์๋ยAccess-Control-Allow-Origin: https://app.newservice.com
๊ณผยAccess-Control-Allow-Credentials: true
๋ฅผ ํจ๊ป ์ค์ ํ์ฌ ํน์ ํ๋ก ํธ์๋์์๋ง ์๊ฒฉ ์ฆ๋ช ๊ธฐ๋ฐ์ ์์ฒญ์ ํ์ฉํ์ต๋๋ค. - ํต์ฌ ๊ฒฐ๊ณผ:
- ๋ณด์ ๊ฐํ: ๋ถํ์ํ Origin์ผ๋ก๋ถํฐ์ ์ ๊ทผ์ ์ฐจ๋จํ์ฌ ๋ฌด๋จ ๋ฐ์ดํฐ ์ ๊ทผ ๋ฐ CSRF ๊ณต๊ฒฉ ์ํ์ ์ต์ํํ์ต๋๋ค.
- ์ ์ฐํ ์๋น์ค ์ฐ๋: ์๋ก์ด ๋ง์ดํฌ๋ก์๋น์ค์ ํ๋ก ํธ์๋ ๊ฐ์ ์์ ์ ์ธ ํต์ ์ฑ๋์ ํ๋ณดํ์ฌ ๊ฐ๋ฐ ๋ฐ ๋ฐฐํฌ ์๋๋ฅผ ๋์์ต๋๋ค.
- ์ฌ์ด ์ ์ง๋ณด์: ๊ฐ ์๋น์ค๋ณ๋ก ํ์ํ CORS ์ ์ฑ ์ Nginx์์ ์ค์ ๊ด๋ฆฌํจ์ผ๋ก์จ, ์ ์ฑ ๋ณ๊ฒฝ ์ ์ฉ์ดํ๊ฒ ๋์ํ ์ ์์์ต๋๋ค.
- ์ฑ๊ณต ์์ธ ๋ถ์: **"์ต์ ๊ถํ์ ์์น"**์ ์ฒ ์ ํ ์งํค๊ณ , ๊ฐ ์๋น์ค์ ํน์ฑ(์๊ฒฉ ์ฆ๋ช
ํ์ ์ฌ๋ถ)์ ๋ง์ถฐ CORS ์ ์ฑ
์ ์ธ๋ถํํ ๊ฒ์ด ์ฃผํจํ์ต๋๋ค. Nginx์ย
location
ย ๋ธ๋ก์ ํ์ฉํ์ฌ ํน์ ๊ฒฝ๋ก์๋ง ํ์ํ CORS ํค๋๋ฅผ ์ ์ฉํจ์ผ๋ก์จ ์ ์ฒด ์์คํ ์ ๋ณด์์ ๊ฐํํ์ต๋๋ค. - [์คํจ ์ฌ๋ก: ์์ผํ ์์ผ๋์นด๋ CORS๋ก ์ธํ ๋ฐ์ดํฐ ์ ์ถ ์๊ธฐ]
- ๋ฐฐ๊ฒฝ: ๋น ๋ฅด๊ฒ ๊ฐ๋ฐ์ ์งํํด์ผ ํ๋ ์คํํธ์
ํ๊ฒฝ์์, ๊ฐ๋ฐ์๋ค์ด "์ผ๋จ ์๋ํ๊ฒ ๋ง๋ค์"๋ ์๊ฐ์ผ๋ก Nginx์ย
http
ย ๋ธ๋ก์ยadd_header 'Access-Control-Allow-Origin' '*';
๋ฅผ ์ค์ ํ๊ณ ๋ฐฐํฌํ์ต๋๋ค. ๋ฐฑ์๋ API๋ ์ฌ์ฉ์ ํ๋กํ ์ ๋ณด๋ฅผ ๋ฐํํ๋ ์๋ํฌ์ธํธ(GET /user/profile
)๋ฅผ ํฌํจํ๊ณ ์์์ผ๋ฉฐ, ์ธ์ฆ๋ ์ฌ์ฉ์์๊ฒ๋ง ์ ๊ทผ์ด ํ์ฉ๋์์ต๋๋ค. - ์คํจ ์์ธ:
- ๊ณผ๋ํ ๊ถํ ๋ถ์ฌ:ย
Access-Control-Allow-Origin: *
ย ์ค์ ์ ๋ชจ๋ ์น์ฌ์ดํธ๊ฐ ์ธ์ฆ๋ ์ฌ์ฉ์์ ๋ธ๋ผ์ฐ์ ๋ฅผ ํตํด ํด๋น API์ ์ ๊ทผํ ์ ์๋๋ก ํ์ฉํ์ต๋๋ค. - ์๊ฒฉ ์ฆ๋ช
๊ณผ์ ๊ฒฐํฉ: ๋น๋กย
Access-Control-Allow-Credentials
๋ ์์์ง๋ง,ย*
ย ์ค์ ์์ฒด๋ง์ผ๋ก๋ ๊ณต๊ฒฉ์๊ฐ ์ ์์ ์ธ ์น์ฌ์ดํธ(evil.com
)๋ฅผ ํตํด ์ฌ์ฉ์์ ๋ธ๋ผ์ฐ์ ์์ยGET /user/profile
ย ์์ฒญ์ ๋ณด๋ด๊ณ , ๊ทธ ์๋ต์ผ๋ก ๋ฐ์ ์ฌ์ฉ์ ํ๋กํ ๋ฐ์ดํฐ๋ฅผ ์ฝ์ด๊ฐ ์ ์๋ ์ฌ๊ฐํ ์ทจ์ฝ์ ์ด ๋ฐ์ํ์ต๋๋ค. (๋ธ๋ผ์ฐ์ ๋ย*
์ธ ๊ฒฝ์ฐ ์๊ฒฉ ์ฆ๋ช ์ ๋ณด๋ด์ง ์์ง๋ง,ยsimple request
์ ๋ํ ์๋ต์ ์ฝ์ ์ ์์ต๋๋ค.) - ์ธ์ ๋ถ์กฑ: ๊ฐ๋ฐํ์ CORS ์ค๋ฅ๋ฅผ ํด๊ฒฐํ๋ค๋ ์๋๊ฐ์ ์ด ์ค์ ์ด ๊ฐ์ ธ์ฌ ์ ์ฌ์ ์ํ์ ์ ๋๋ก ์ธ์งํ์ง ๋ชปํ์ต๋๋ค.
- ์ป์ ๊ตํ: ๋ณด์ ์ปจ์คํ
์ค ์ด ์ทจ์ฝ์ ์ด ๋ฐ๊ฒฌ๋์๊ณ , ์ฆ์ย
Access-Control-Allow-Origin: *
๋ฅผ ์ ๊ฑฐํ๊ณ ํน์ Origin๋ง ํ์ฉํ๋๋ก ์์ ํ์ต๋๋ค. ์ด ๊ฒฝํ์ ํตํด ๊ฐ๋ฐํ์ **"๋น ๋ฅธ ๊ฐ๋ฐ๋งํผ ์ค์ํ ๊ฒ์ ์์ ํ ๊ฐ๋ฐ"**์ด๋ผ๋ ๊ตํ์ ์ป์์ผ๋ฉฐ, ๋ชจ๋ API ์๋ํฌ์ธํธ์ ๋ํด ์ฒ ์ ํ ๋ณด์ ๊ฒํ ํ๋ก์ธ์ค๋ฅผ ๋์ ํ๊ฒ ๋์์ต๋๋ค.ยAccess-Control-Allow-Origin: *
๋ ๋งค์ฐ ์ํํ๋ฉฐ, ํนํ ์ธ์ฆ์ด ํ์ํ API์์๋ ์ ๋ ์ฌ์ฉํด์๋ ์ ๋๋ค๋ ์ ์ ๊นจ๋ฌ์์ต๋๋ค.
โ ์์ฃผ ๋ฌป๋ ์ง๋ฌธ(FAQ)
- Q1.ย
Access-Control-Allow-Origin: *
๋ ์ ์ํํ๊ฐ์? - A1. ๋ชจ๋ ์น์ฌ์ดํธ๊ฐ ๊ทํ์ ์๋น์ค API์ ์ ๊ทผํ ์ ์๋๋ก ํ์ฉํ๊ธฐ ๋๋ฌธ์ ๋๋ค. ํนํ ์ฌ์ฉ์๊ฐ ๋ก๊ทธ์ธ๋์ด ์๋ ์ํ๋ผ๋ฉด, ์ ์์ ์ธ ์ฌ์ดํธ๊ฐ ์ฌ์ฉ์์ ๋ธ๋ผ์ฐ์ ๋ฅผ ํตํด ๋ฏผ๊ฐํ ๋ฐ์ดํฐ๋ฅผ ์ฝ์ด๊ฐ๊ฑฐ๋ ์์น ์๋ ์์ ์ ์ํํ๋๋ก ์ ๋ํ ์ ์์ต๋๋ค.
- Q2.ย
Access-Control-Allow-Origin
์ ์ฌ๋ฌ ๊ฐ ์ค์ ํ ์ ์๋์? - A2. Nginx์ย
add_header
ย ์ง์๋ฌธ์ ๋จ์ผ ๊ฐ๋ง ๊ฐ์ง ์ ์์ต๋๋ค. ์ฌ๋ฌ Origin์ ํ์ฉํ๋ ค๋ฉดยif
ย ๋ฌธ๊ณผย$http_origin
ย ๋ณ์๋ฅผ ์ฌ์ฉํ๊ฑฐ๋,ยmap
ย ๋ชจ๋์ ํ์ฉํ์ฌ ๋์ ์ผ๋ก Origin์ ์ค์ ํด์ผ ํฉ๋๋ค. - Q3.ย
OPTIONS
ย ์์ฒญ(Preflight)์ ๋ฌด์์ด๊ณ ์ ํ์ํ๊ฐ์? - A3. ์ค์ ์์ฒญ์ ๋ณด๋ด๊ธฐ ์ ์ ๋ธ๋ผ์ฐ์ ๊ฐ ์๋ฒ์๊ฒ "์ด๋ฐ ์์ฒญ์ ๋ณด๋ด๋ ๋ ๊น์?"๋ผ๊ณ ๋ฌป๋ ์ผ์ข
์ ์ฌ์ ํ์ธ ์์ฒญ์
๋๋ค.ย
POST
,ยPUT
,ยDELETE
์ ๊ฐ์ ๋ฉ์๋๋ ์ปค์คํ ํค๋๋ฅผ ํฌํจํ๋ ์์ฒญ์ผ ๊ฒฝ์ฐ ๋ณด์์ ์ํด ํ์์ ์ผ๋ก ๋ฐ์ํฉ๋๋ค. ์๋ฒ๋ยOPTIONS
ย ์์ฒญ์ ๋ํด ํ์ฉ ์ฌ๋ถ๋ฅผ ์๋ตํด์ผ ํฉ๋๋ค. - Q4.ย
Access-Control-Allow-Credentials: true
๋ ์ธ์ ์ฌ์ฉํด์ผ ํ๋์? - A4. ์ฟ ํค, HTTP ์ธ์ฆ ํค๋, ํด๋ผ์ด์ธํธ SSL ์ธ์ฆ์์ ๊ฐ์ ์ฌ์ฉ์ ์๊ฒฉ ์ฆ๋ช
์ ํฌํจํ๋ ์์ฒญ์ ํ์ฉํ ๋ ์ฌ์ฉํฉ๋๋ค.ย ์ด ๊ฒฝ์ฐย
Access-Control-Allow-Origin: *
๋ ์ ๋ ์ฌ์ฉํ ์ ์์ผ๋ฉฐ, ๋ฐ๋์ ํน์ Origin์ ๋ช ์ํด์ผ ํฉ๋๋ค. - Q5. CORS ์ค๋ฅ๊ฐ ๋ฐ์ํ๋ฉด ์ด๋ป๊ฒ ๋๋ฒ๊น ํด์ผ ํ๋์?
- A5. ๋ธ๋ผ์ฐ์ ๊ฐ๋ฐ์ ๋๊ตฌ(F12)์ '๋คํธ์ํฌ' ํญ์ ์ด๊ณ , ์คํจํ ์์ฒญ์ ํด๋ฆญํ ํ 'ํค๋' ์น์
์ ํ์ธํ์ธ์. ํนํ '์๋ต ํค๋'์ย
Access-Control-Allow-Origin
ย ๋ฐ ๋ค๋ฅธ CORS ๊ด๋ จ ํค๋๋ค์ด ์ฌ๋ฐ๋ฅด๊ฒ ํฌํจ๋์ด ์๋์ง, ๊ทธ๋ฆฌ๊ณ ์์ฒญ 'Origin'๊ณผ ์ผ์นํ๋์ง ํ์ธํ๋ ๊ฒ์ด ์ค์ํฉ๋๋ค. - Q6. Nginx์์ ํน์ IP ์ฃผ์์๋ง CORS๋ฅผ ํ์ฉํ ์ ์๋์?
- A6.ย
if ($remote_addr = 'ํน์ IP')
์ ๊ฐ์ ์กฐ๊ฑด๋ฌธ์ผ๋กยadd_header
๋ฅผ ์ ์ดํ ์ ์์ต๋๋ค. ํ์ง๋ง ์ด๋ ํด๋ผ์ด์ธํธ์ IP ์ฃผ์๋ฅผ ๊ธฐ์ค์ผ๋ก ํ๋ฏ๋ก, ํ๋ก์ ํ๊ฒฝ์์๋ยX-Forwarded-For
ย ํค๋๋ฅผ ํ์ฉํ๋ ๋ฑ ์ถ๊ฐ์ ์ธ ๊ณ ๋ ค๊ฐ ํ์ํฉ๋๋ค. ์ผ๋ฐ์ ์ผ๋ก CORS๋ Origin(๋๋ฉ์ธ) ๊ธฐ๋ฐ์ผ๋ก ๋์ํฉ๋๋ค. - Q7. CORS ์ ์ฑ ์ ์ค์ ํ๋๋ฐ๋ ์ฌ์ ํ ์๋ฌ๊ฐ ๋ฐ์ํฉ๋๋ค.
- A7. ๋ค์์ ํ์ธํด ๋ณด์ธ์: Nginx ์ค์ ์ฌ๋ก๋/์ฌ์์ ์ฌ๋ถ, ๋ธ๋ผ์ฐ์ ์บ์ ๋ฌธ์ (ํ๋ ์๋ก๊ณ ์นจ),ย
OPTIONS
ย ์์ฒญ ์ฒ๋ฆฌ ๋๋ฝ,ยAccess-Control-Allow-Origin
์ ์คํ๊ฐ ์๊ฑฐ๋ ํ๋กํ ์ฝ(http/https)์ด ์ผ์นํ์ง ์๋ ๊ฒฝ์ฐ,ยAccess-Control-Allow-Credentials
์ย*
์ ๋์ ์ฌ์ฉ ์ฌ๋ถ.
๐ก Nginx CORS ์ ์ฑ : ์ค์ ์ด์ ํ & ์ฃผ์์ฌํญ
- [ํ 1:ย
Vary: Origin
ย ํค๋ ์ถ๊ฐ๋ก ์บ์ ๋ฌด๊ฒฐ์ฑ ํ๋ณด]: ๐ฏ Nginx์์ ํ๋ก์ ์บ์ฑ์ ์ฌ์ฉํ๋ค๋ฉด,ยadd_header Vary Origin;
์ ์ถ๊ฐํ์ฌยOrigin
ย ํค๋ ๊ฐ์ ๋ฐ๋ผ ์๋ต์ ์บ์ํ๋๋ก ํ์ธ์. ์ด๋ ๋ค๋ฅธ Origin์ ํด๋ผ์ด์ธํธ๊ฐ ์ด์ Origin์ ์บ์๋ ์๋ต์ ๋ฐ์ CORS ๋ฌธ์ ๊ฐ ๋ฐ์ํ๋ ๊ฒ์ ๋ฐฉ์งํฉ๋๋ค. - [ํ 2: Preflight ์์ฒญ์ย
Access-Control-Max-Age
ย ํ์ฉ]: ๐ยOPTIONS
ย ์์ฒญ์ ๋ํ ์๋ต์ยadd_header 'Access-Control-Max-Age' 1728000;
ย (์ด ๋จ์, ์: 20์ผ)๋ฅผ ์ถ๊ฐํ๋ฉด, ๋ธ๋ผ์ฐ์ ๊ฐ ํด๋น ๊ธฐ๊ฐ ๋์ Preflight ์์ฒญ ๊ฒฐ๊ณผ๋ฅผ ์บ์ํ์ฌ ๋ถํ์ํยOPTIONS
ย ์์ฒญ์ ์ค์ด๊ณ ์ฑ๋ฅ์ ํฅ์์ํฌ ์ ์์ต๋๋ค. - [ํ 3: ๋์ Origin ํ์ฉ์ ์ํย
map
ย ๋ชจ๋ ์ฌ์ฉ]: โ๏ธ ์ฌ๋ฌ ๊ฐ์ ํน์ Origin์ ํ์ฉํด์ผ ํ์ง๋งยif
ย ๋ฌธ์ ๋ณต์ก์ฑ์ ํผํ๊ณ ์ถ๋ค๋ฉด, Nginx์ยmap
ย ๋ชจ๋์ ์ฌ์ฉํ์ฌย$http_origin
ย ๋ณ์์ ๋ฐ๋ผยAccess-Control-Allow-Origin
ย ๊ฐ์ ๋์ ์ผ๋ก ์ค์ ํ ์ ์์ต๋๋ค.
# http ๋ธ๋ก ๋ด์ ์ ์ map $http_origin $cors_origin { default ""; "https://app.example.com" "https://app.example.com"; "https://admin.example.com" "https://admin.example.com"; } # server ๋๋ location ๋ธ๋ก ๋ด์์ ์ฌ์ฉ # if ($cors_origin ~ ".+") { # $cors_origin์ด ๋น์ด์์ง ์๋ค๋ฉด # add_header 'Access-Control-Allow-Origin' $cors_origin; # }
- [ํ 4: ๋ณด์ ํค๋์ CORS ์ ์ฑ
์ ์กฐํ]: ๐ก๏ธ CORS ์ ์ฑ
์ธ์๋ย
X-Frame-Options
,ยX-Content-Type-Options
,ยX-XSS-Protection
,ยContent-Security-Policy
ย ๋ฑ ๋ค๋ฅธ ๋ณด์ ํค๋๋ค์ ํจ๊ป ์ค์ ํ์ฌ ์น ์ ํ๋ฆฌ์ผ์ด์ ์ ์ ๋ฐ์ ์ธ ๋ณด์ ์์ค์ ๋์ด๋ ๊ฒ์ด ์ค์ํฉ๋๋ค. Nginxยnginx.conf
ย ํ์ผ์๋ ์ด๋ฏธ ์ด๋ฌํ ๋ณด์ ํค๋ ์ค์ ๋ค์ด ํฌํจ๋์ด ์์ผ๋ ์ฐธ๊ณ ํ์ธ์.
๐ ๊ฒฐ๋ก ๋ฐ ๋ค์ ๋จ๊ณ
- [ํต์ฌ ์์ฝ]: Nginx CORS ์ ์ฑ
์ ๋จ์ํ ์ค์ ์ค๋ฅ ๋ฌธ์ ๊ฐ ์๋, ์น ๋ณด์์ ํต์ฌ์ ์ธ ๋ถ๋ถ์
๋๋ค.ย
Access-Control-Allow-Origin: *
์ ๊ฐ์ ์์ผ๋์นด๋ ์ฌ์ฉ์ ์น๋ช ์ ์ธ ๋ณด์ ์ทจ์ฝ์ ์ผ๋ก ์ด์ด์ง ์ ์์์ ์ดํดํ๊ณ , ํญ์ ์ต์ ๊ถํ์ ์์น์ ๋ฐ๋ผ ํน์ Origin๋ง์ ํ์ฉํ๋๋ก ์ ์คํ๊ฒ ์ค์ ํด์ผ ํฉ๋๋ค.ยOPTIONS
ย Preflight ์์ฒญ ์ฒ๋ฆฌ,ยAccess-Control-Allow-Credentials
ย ์ฌ์ฉ ์ ์ฃผ์์ฌํญ ๋ฑ์ ๊ณ ๋ คํ์ฌ ์์ ํ๊ณ ํจ์จ์ ์ธ ์น ์๋น์ค๋ฅผ ๊ตฌ์ถํ๋ ๊ฒ์ด ์ค์ํฉ๋๋ค. - [๋ค์ ๋จ๊ณ ์ ์]:
- Nginx ๊ณต์ ๋ฌธ์ ์ฌํ ํ์ต:ย
ngx_http_headers_module
ย ์ธ์๋ยngx_http_map_module
,ยngx_http_core_module
ย ๋ฑ์ ํ์ตํ์ฌ Nginx ์ค์ ์ ๊น์ด๋ฅผ ๋ํด๋ณด์ธ์. - ๋ณด์ ์ปจ์คํ /๊ฐ์ฌ: ์๋น์ค๊ฐ ์ฑ์ฅํจ์ ๋ฐ๋ผ ์ ๊ธฐ์ ์ธ ์น ๋ณด์ ๊ฐ์ฌ ๋๋ ์ปจ์คํ ์ ํตํด ์ ์ฌ์ ์ทจ์ฝ์ ์ ์ฌ์ ์ ํ์ ํ๊ณ ๊ฐ์ ํ๋ ๋ ธ๋ ฅ์ ๊ธฐ์ธ์ด์ธ์.
- ๊ด๋ จ ํ๋ก์ ํธ ์ฐธ์ฌ: GitHub ๋ฑ์์ ์คํ ์์ค Nginx ์ค์ ํ๋ก์ ํธ๋ฅผ ์ดํด๋ณด๋ฉฐ ๋ค๋ฅธ ์ ๋ฌธ๊ฐ๋ค์ ์ค์ ๋ฐฉ์์ ๋ฐฐ์ฐ๊ณ , ์์ ์ ๊ฒฝํ์ ๊ณต์ ํ๋ฉฐ ํจ๊ป ์ฑ์ฅํด ๋ณด์ธ์.
ย
๋๊ธ
๋๊ธ ๋ก๋ฉ ์ค...