728x90
반응형
🌐 CORS와 Preflight Request
13살도 이해하는 완전 정복 가이드
1. CORS가 뭔가요? 🤔
집 방문 비유로 이해하기
❌ CORS 없이 (거절당함)
너: "안녕? 놀러 왔어!"
친구 엄마: "너희 집 주소가 어디야?"
너: "123번지요"
친구 엄마: "우린 456번지만 받아. 돌아가!"
→ 거절당함 😢
✅ CORS 있으면 (환영받음)
친구 엄마: "123번지에서 오는 친구는 환영해!"
너: "안녕? 놀러 왔어!"
친구 엄마: "어서와!"
→ 환영받음 🎉
🌐 웹사이트로 치면
프론트엔드 (http://localhost:8080)
"안녕, 백엔드야! 데이터 줘!"
↓
❌ 브라우저가 막음
"너희 집 주소(Origin)가 달라서 안 돼!"
↓
백엔드 (http://localhost:3000)
"나는 8080에서 오는 애들 환영해!"
↓
✅ 브라우저가 허용
"오케이, 주인이 허락했네!"
2. Preflight Request가 뭔가요? 🚦
더 까다로운 방문
일반 방문 (Simple Request)
너: *똑똑* "안녕? 들어가도 돼?"
친구 엄마: "어서와!" ✅
→ 바로 들어감
까다로운 방문 (Preflight Request)
너: "나 큰 짐 들고 갈 건데..." (복잡한 요청)
친구 엄마: "잠깐! 뭐 가져올 건데?" 🤔
너: "게임기랑 간식이요" (OPTIONS 요청)
친구 엄마: "오케이, 들어와!" ✅
너: *게임기 들고 입장*
만약 친구 엄마가 "안 돼!" ❌ 하면
→ 너는 들어갈 수 없음 (Preflight 실패)
📊 언제 Preflight가 발생하나요?
| 요청 타입 | 예시 | Preflight 필요? |
|---|---|---|
| Simple | GET 요청 | ❌ 불필요 |
| Simple | 기본 POST (form 데이터) | ❌ 불필요 |
| Preflight | POST + JSON | ✅ 필요 |
| Preflight | 커스텀 헤더 (Authorization) | ✅ 필요 |
| Preflight | PUT, DELETE 메서드 | ✅ 필요 |

3. Preflight 동작 과정 🔄
1단계: 브라우저가 먼저 물어봄 (Preflight)
OPTIONS http://localhost:3000/api/users
Origin: http://localhost:8080
Access-Control-Request-Method: POST ← "POST 써도 돼?"
Access-Control-Request-Headers: Content-Type ← "이 헤더 써도 돼?"
↓
2단계: 백엔드가 답변 (중요!)
HTTP/1.1 200 OK ← 이게 중요! 200이어야 함!
Access-Control-Allow-Origin: http://localhost:8080 ← "너 환영해"
Access-Control-Allow-Methods: POST, GET, PUT ← "POST 가능"
Access-Control-Allow-Headers: Content-Type ← "그 헤더 가능"
↓
3단계: 브라우저 판단
"오케이 받았네! 이제 진짜 요청 보낸다!"
↓
4단계: 실제 요청 보냄
POST http://localhost:3000/api/users
Content-Type: application/json
{ "name": "John" }
4. 흔한 에러와 해결 방법 🔧
❌ 에러: "doesn't pass access control check: It does not have HTTP ok status"
원인: 백엔드가 OPTIONS 요청에 200 OK를 보내지 않음
브라우저: "OPTIONS 요청 보냄"
백엔드: (아무 응답 없음) 또는 (404 Not Found)
브라우저: "200 OK를 못 받았네? 실패!"
✅ 해결: CORS 미들웨어 사용
// app.js
const createCorsMiddleware = require('./middlewares/security/cors');
// 모든 OPTIONS 요청을 자동으로 처리!
app.use(createCorsMiddleware({
allowedOrigins: ['http://localhost:8080']
}));
// 이제 POST만 신경 쓰면 됨
app.post('/api/users', (req, res) => {
res.json({ success: true });
});
🛠️ CORS 미들웨어 구현
// middlewares/security/cors.js
const createCorsMiddleware = (options = {}) => {
const allowedOrigins = options.allowedOrigins || ['http://localhost:8080'];
return (req, res, next) => {
const origin = req.headers.origin;
// 1. Origin 체크
if (allowedOrigins.includes(origin)) {
res.setHeader('Access-Control-Allow-Origin', origin);
res.setHeader('Access-Control-Allow-Credentials', 'true');
}
// 2. OPTIONS 요청 처리 (Preflight!)
if (req.method === 'OPTIONS') {
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE');
res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization');
return res.sendStatus(200); ← 여기서 200 보내서 Preflight 통과!
}
// 3. 일반 요청은 계속 진행
next();
};
};
5. 핵심 요약 🎯
CORS란?
"다른 집 주소(Origin)에서 오는 손님을 관리하는 것"
Preflight란?
"복잡한 요청 보내기 전에 브라우저가 먼저 물어보는 것"
왜 필요한가?
"보안상 위험한 요청을 사전에 차단하기 위해"
어떻게 해결하나?
"OPTIONS 요청에 200 OK를 반드시 보내기!"
✅ 완벽한 해결 체크리스트
- ✓ CORS 미들웨어를 모든 라우트 전에 등록
- ✓ OPTIONS 메서드 처리 구현
- ✓ Access-Control-Allow-Origin 헤더 설정
- ✓ Access-Control-Allow-Methods 헤더 설정
- ✓ Access-Control-Allow-Headers 헤더 설정
- ✓ 200 OK 상태 코드 반환
728x90
'Tech Notes' 카테고리의 다른 글
| AWS bucket의 권한 관리 (0) | 2025.10.10 |
|---|---|
| The bucket does not allow ACLs... (0) | 2025.10.10 |
| aws access key, secret access key 생성하기 (0) | 2025.10.10 |
| aws s3 생성방법 (0) | 2025.10.10 |
| aws 요금 알림 서비스 설정하기 (0) | 2025.10.10 |