๋ชฉ์ฐจ
- ๊ฐ๋ฐํ๋ค๊ฐ ๊ฐ์๊ธฐ ๋งํ๋ ๊ทธ ์ค๋ฅ
- ๋์ผ ์ถ์ฒ ์ ์ฑ (Same-Origin Policy)์ด๋?
- CORS๋ ๋ฌด์์ธ๊ฐ?
- CORS ์ค๋ฅ๊ฐ ๋ฐ์ํ๋ ์ํฉ
- CORS ์ค๋ฅ๋ฅผ ํด๊ฒฐํ๋ ๋ฐฉ๋ฒ
- CORS ๊ด๋ จ HTTP ํค๋ ์ดํดํ๊ธฐ
- Preflight ์์ฒญ์ด๋?
- ์ ๋ฆฌ ๋ฐ ๋ค์ ๋จ๊ณ
1. ๊ฐ๋ฐํ๋ค๊ฐ ๊ฐ์๊ธฐ ๋งํ๋ ๊ทธ ์ค๋ฅ
์น ๊ฐ๋ฐ์ ์ฒ์ ์์ํ๋ฉด ๋ฐ๋์ ํ ๋ฒ์ ๋ง์ฃผ์น๋ ์ค๋ฅ๊ฐ ์์ต๋๋ค. ๋ธ๋ผ์ฐ์ ์ฝ์์ ๋ค์๊ณผ ๊ฐ์ ๋ฉ์์ง๊ฐ ๋จ๋ฉด์ API ์์ฒญ์ด ๋งํ๋ ์ํฉ์ ๋๋ค.
Access to fetch at 'https://api.example.com' from origin 'http://localhost:3000' has been blocked by CORS policy.
์ด ์ค๋ฅ๋ฅผ ์ฒ์ ๋ณด๋ฉด ๋ฌด์จ ์๋ฏธ์ธ์ง, ์ด๋ป๊ฒ ํด๊ฒฐํด์ผ ํ๋์ง ๋นํฉ์ค๋ฝ์ต๋๋ค. ์ด ๊ธ์์๋ CORS๊ฐ ์ ์กด์ฌํ๋์ง, ์ค๋ฅ๊ฐ ์ ๋ฐ์ํ๋์ง, ์ด๋ป๊ฒ ํด๊ฒฐํ๋์ง๋ฅผ ๋จ๊ณ๋ณ๋ก ์ค๋ช ๋๋ฆฝ๋๋ค.
2. ๋์ผ ์ถ์ฒ ์ ์ฑ (Same-Origin Policy)์ด๋?
CORS๋ฅผ ์ดํดํ๋ ค๋ฉด ๋จผ์ **๋์ผ ์ถ์ฒ ์ ์ฑ (Same-Origin Policy)**์ ์์์ผ ํฉ๋๋ค.
๋ธ๋ผ์ฐ์ ๋ ๋ณด์์์ ์ด์ ๋ก ๋ค๋ฅธ ์ถ์ฒ์์ ์จ ๋ฆฌ์์ค๋ฅผ ๊ธฐ๋ณธ์ ์ผ๋ก ์ฐจ๋จํฉ๋๋ค. ์ฌ๊ธฐ์ ์ถ์ฒ(Origin)๋ ํ๋กํ ์ฝ + ๋๋ฉ์ธ + ํฌํธ์ ์กฐํฉ์ ๋๋ค.
์๋ฅผ ๋ค์ด http://localhost:3000๊ณผ http://localhost:8080์ ํฌํธ๊ฐ ๋ค๋ฅด๊ธฐ ๋๋ฌธ์ ์๋ก ๋ค๋ฅธ ์ถ์ฒ์ ๋๋ค. http://example.com๊ณผ https://example.com์ ํ๋กํ ์ฝ์ด ๋ฌ๋ผ ๋ค๋ฅธ ์ถ์ฒ์ ๋๋ค.
์ด ์ ์ฑ ์ด ์กด์ฌํ๋ ์ด์ ๋ ์ ์์ ์ธ ์ฌ์ดํธ๊ฐ ์ฌ์ฉ์ ๋ชจ๋ฅด๊ฒ ๋ค๋ฅธ ์ฌ์ดํธ์ API๋ฅผ ํธ์ถํด ๊ฐ์ธ์ ๋ณด๋ฅผ ํ์ทจํ๋ ๊ฒ์ ๋ง๊ธฐ ์ํด์์ ๋๋ค.
3. CORS๋ ๋ฌด์์ธ๊ฐ?
**CORS(Cross-Origin Resource Sharing)**๋ ๋์ผ ์ถ์ฒ ์ ์ฑ ์ ์์ธ๋ฅผ ํ์ฉํ๋ ๋ฉ์ปค๋์ฆ์ ๋๋ค. ์๋ฒ๊ฐ "ํน์ ์ถ์ฒ์์ ์ค๋ ์์ฒญ์ ํ์ฉํ๋ค"๊ณ ๋ธ๋ผ์ฐ์ ์๊ฒ ์๋ ค์ฃผ๋ ๋ฐฉ์์ ๋๋ค.
์ฆ, CORS๋ ์๋ฒ๊ฐ ์ค์ ํ๋ ๊ฒ์ ๋๋ค. ๋ธ๋ผ์ฐ์ ๊ฐ ์์ฒญ์ ๋ง๋ ๊ฒ์ด ์๋๋ผ, ์๋ฒ๊ฐ ํ์ฉ ์ถ์ฒ๋ฅผ ๋ช ์ํด์ฃผ์ง ์์์ ๋ธ๋ผ์ฐ์ ๊ฐ ์ฐจ๋จํ๋ ๊ฒ์ ๋๋ค.
CORS ์ค๋ฅ๋ ๋ธ๋ผ์ฐ์ ์์๋ง ๋ฐ์ํฉ๋๋ค. Postman์ด๋ curl ๊ฐ์ ๋๊ตฌ๋ก ๊ฐ์ API๋ฅผ ํธ์ถํ๋ฉด ์ ์์ ์ผ๋ก ์๋ต์ด ์ต๋๋ค. ์ด ์ฐจ์ด๊ฐ CORS๋ฅผ ์ดํดํ๋ ํต์ฌ์ ๋๋ค.
4. CORS ์ค๋ฅ๊ฐ ๋ฐ์ํ๋ ์ํฉ
๊ฐ์ฅ ํํ CORS ์ค๋ฅ ์ํฉ์ ๋๋ค.
ํ๋ก ํธ์๋๊ฐ http://localhost:3000์์ ์คํ ์ค์ธ๋ฐ, ๋ฐฑ์๋ API๊ฐ http://localhost:8080์ ์์ ๋ ๋ฐ์ํฉ๋๋ค. ํ๋ก ํธ์๋ ๋ฐฐํฌ ์ฃผ์๊ฐ https://myblog.com์ธ๋ฐ, API ์๋ฒ๋ https://api.myblog.com์ ์์ ๋๋ ๋ฐ์ํฉ๋๋ค. ์ธ๋ถ API๋ฅผ ๋ธ๋ผ์ฐ์ ์์ ์ง์ ํธ์ถํ ๋ ํด๋น API ์๋ฒ๊ฐ CORS๋ฅผ ํ์ฉํ์ง ์์ผ๋ฉด ๋ฐ์ํฉ๋๋ค.
5. CORS ์ค๋ฅ๋ฅผ ํด๊ฒฐํ๋ ๋ฐฉ๋ฒ
CORS ์ค๋ฅ๋ ์๋ฒ ์ชฝ์์ ํ์ฉ ์ถ์ฒ๋ฅผ ์ค์ ํด์ผ ํด๊ฒฐ๋ฉ๋๋ค.
Node.js (Express) ์๋ฒ์์ CORS ์ค์ cors ํจํค์ง๋ฅผ ์ค์นํ๊ณ ๋ฏธ๋ค์จ์ด๋ก ๋ฑ๋กํฉ๋๋ค.
npm install cors
const cors = require('cors');
app.use(cors({ origin: 'http://localhost:3000' }));
๋ชจ๋ ์ถ์ฒ๋ฅผ ํ์ฉํ๊ณ ์ถ๋ค๋ฉด origin: '*'์ผ๋ก ์ค์ ํฉ๋๋ค. ๋จ, ์ค์๋น์ค์์ ๋ชจ๋ ์ถ์ฒ๋ฅผ ํ์ฉํ๋ ๊ฒ์ ๋ณด์์ ์ข์ง ์์ผ๋ฏ๋ก ํ์ฉํ ์ถ์ฒ๋ฅผ ๋ช ์์ ์ผ๋ก ์ง์ ํ๋ ๊ฒ์ด ์ข์ต๋๋ค.
Nginx์์ CORS ํค๋ ์ถ๊ฐ Nginx ์ค์ ํ์ผ์ location ๋ธ๋ก์ ์๋ ํค๋๋ฅผ ์ถ๊ฐํฉ๋๋ค.
add_header 'Access-Control-Allow-Origin' 'https://myblog.com';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
Spring Boot์์ CORS ์ค์ ์ปจํธ๋กค๋ฌ๋ ์ค์ ํด๋์ค์์ @CrossOrigin ์ด๋ ธํ ์ด์ ๋๋ WebMvcConfigurer๋ฅผ ์ฌ์ฉํด ํ์ฉ ์ถ์ฒ๋ฅผ ๋ฑ๋กํฉ๋๋ค.
6. CORS ๊ด๋ จ HTTP ํค๋ ์ดํดํ๊ธฐ
CORS๋ HTTP ํค๋๋ฅผ ํตํด ๋์ํฉ๋๋ค. ์ฃผ์ ํค๋๋ฅผ ์์๋๋ฉด ์ค๋ฅ ๋ฉ์์ง๋ฅผ ํด์ํ๋ ๋ฐ ๋์์ด ๋ฉ๋๋ค.
์๋ฒ๊ฐ ์๋ต์ ํฌํจํ๋ ํค๋
Access-Control-Allow-Origin์ ์ด๋ค ์ถ์ฒ์์ ์ค๋ ์์ฒญ์ ํ์ฉํ ์ง ์ง์ ํฉ๋๋ค. https://myblog.com ์ฒ๋ผ ํน์ ๋๋ฉ์ธ์ ์ง์ ํ๊ฑฐ๋, *๋ก ๋ชจ๋ ์ถ์ฒ๋ฅผ ํ์ฉํ ์ ์์ต๋๋ค.
Access-Control-Allow-Methods๋ ํ์ฉํ๋ HTTP ๋ฉ์๋๋ฅผ ์ง์ ํฉ๋๋ค. GET, POST, PUT, DELETE ์ฒ๋ผ ๋ช ์ํฉ๋๋ค.
Access-Control-Allow-Headers๋ ์์ฒญ์ ํฌํจํ ์ ์๋ ํค๋๋ฅผ ์ง์ ํฉ๋๋ค. Authorization, Content-Type ์ฒ๋ผ ๋ช ์ํฉ๋๋ค.
Access-Control-Max-Age๋ Preflight ์์ฒญ์ ๊ฒฐ๊ณผ๋ฅผ ๋ธ๋ผ์ฐ์ ๊ฐ ์บ์ํ๋ ์๊ฐ(์ด)์ ์ง์ ํฉ๋๋ค.
7. Preflight ์์ฒญ์ด๋?
๋ธ๋ผ์ฐ์ ๋ ์ค์ ์์ฒญ์ ๋ณด๋ด๊ธฐ ์ ์ ์๋ฒ๊ฐ ํด๋น ์์ฒญ์ ํ์ฉํ๋์ง ๋จผ์ ํ์ธํ๋ Preflight ์์ฒญ์ ๋ณด๋ด๋ ๊ฒฝ์ฐ๊ฐ ์์ต๋๋ค.
Preflight ์์ฒญ์ OPTIONS ๋ฉ์๋๋ก ์ ์ก๋๋ฉฐ, ์๋ฒ๊ฐ ํด๋น ์ถ์ฒ์ ๋ฉ์๋๋ฅผ ํ์ฉํ๋ค๊ณ ์๋ตํ๋ฉด ์ค์ ์์ฒญ์ ๋ณด๋ ๋๋ค.
Preflight ์์ฒญ์ด ๋ฐ์ํ๋ ์กฐ๊ฑด์ GET, POST, HEAD ์ด์ธ์ ๋ฉ์๋๋ฅผ ์ฌ์ฉํ ๋, Content-Type์ด application/json์ธ ๊ฒฝ์ฐ, ์ปค์คํ ํค๋(์: Authorization)๋ฅผ ํฌํจํ๋ ๊ฒฝ์ฐ์ ๋๋ค.
์๋ฒ์์ OPTIONS ์์ฒญ์ ์ฒ๋ฆฌํ๋๋ก ์ค์ ํ์ง ์์ผ๋ฉด Preflight ๋จ๊ณ์์ CORS ์ค๋ฅ๊ฐ ๋ฐ์ํฉ๋๋ค.
8. ์ ๋ฆฌ ๋ฐ ๋ค์ ๋จ๊ณ
์ค๋ ๋ฐฐ์ด ํต์ฌ์ ์ ๋ฆฌํฉ๋๋ค.
- ๋์ผ ์ถ์ฒ ์ ์ฑ ๋๋ฌธ์ ๋ธ๋ผ์ฐ์ ๋ ๊ธฐ๋ณธ์ ์ผ๋ก ๋ค๋ฅธ ์ถ์ฒ์ ๋ฆฌ์์ค ์์ฒญ์ ์ฐจ๋จํฉ๋๋ค.
- CORS๋ ์๋ฒ๊ฐ ํน์ ์ถ์ฒ์ ์์ฒญ์ ํ์ฉํ๋๋ก ๋ธ๋ผ์ฐ์ ์ ์๋ ค์ฃผ๋ ๋ฉ์ปค๋์ฆ์ ๋๋ค.
- CORS ์ค๋ฅ๋ ์๋ฒ์์ Access-Control-Allow-Origin ํค๋๋ฅผ ์ค์ ํด ํด๊ฒฐํฉ๋๋ค.
- CORS ์ค๋ฅ๋ ๋ธ๋ผ์ฐ์ ์์๋ง ๋ฐ์ํ๋ฉฐ, Postman ๊ฐ์ ๋๊ตฌ์์๋ ๋ฐ์ํ์ง ์์ต๋๋ค.
- ์ค์๋น์ค์์๋ ๋ชจ๋ ์ถ์ฒ(*)๋ฅผ ํ์ฉํ์ง ๋ง๊ณ ํ์ํ ๋๋ฉ์ธ๋ง ๋ช ์์ ์ผ๋ก ํ์ฉํฉ๋๋ค.
๋ค์ ๊ธ์์๋ ์น์์ผ(WebSocket)์ด๋ ๋ฌด์์ธ์ง, ์ค์๊ฐ ์ฑํ ์ด ๋๋ ์๋ฆฌ๋ฅผ ์์๋ณด๊ฒ ์ต๋๋ค.