728x90
1. CORS란?
- Cross-Origin Resource Sharing
- 브라우저 보안 정책(Same-Origin Policy) 때문에
- 다른 오리진(도메인/포트/스킴) 으로 요청할 때 제약이 생김.
- 서버가 응답 헤더로 허용을 명시해야 브라우저가 요청 결과를 넘겨줌.
2. 오리진(Origin) 구분
오리진은 스킴 + 도메인 + 포트
- 같은 오리진: http://localhost:8080 → http://localhost:8080
- 다른 오리진:
- http://localhost:8080 → http://localhost:3000 (포트 다름)
- http://localhost:8080 → https://localhost:8080 (스킴 다름)
- http://localhost:8080 → https://api.example.com:443 (도메인 다름)
3. 단순 요청(Simple Request)
브라우저가 프리플라이트 없이 바로 요청하는 경우.
조건:
- 메서드: GET, POST, HEAD
- POST일 때 Content-Type:
- application/x-www-form-urlencoded
- multipart/form-data
- text/plain
- 커스텀 헤더 없음 (Authorization, X-* 등 금지)
👉 이 경우 서버는 Access-Control-Allow-Origin만 있으면 OK
예:
GET /data
Origin: <http://localhost:8080>
응답:
200 OK
Access-Control-Allow-Origin: <http://localhost:8080>
4. 프리플라이트 요청 (Preflight Request)
단순 요청 조건을 벗어나면 브라우저는 사전 확인 요청(OPTIONS) 을 먼저 보냄.
예:
fetch("<https://api.example.com/data>", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Authorization": "Bearer token"
},
body: JSON.stringify({ a: 1 })
})
➡ 브라우저가 먼저 보냄:
OPTIONS /data
Origin: <http://localhost:8080>
Access-Control-Request-Method: POST
Access-Control-Request-Headers: Content-Type, Authorization
서버 응답 예:
204 No Content
Access-Control-Allow-Origin: <http://localhost:8080>
Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS
Access-Control-Allow-Headers: Content-Type, Authorization
Access-Control-Allow-Credentials: true
그 후에야 브라우저가 실제 POST /data 요청을 전송.
5. 필수 CORS 응답 헤더
- Access-Control-Allow-Origin: 허용할 Origin
- Access-Control-Allow-Credentials: 인증/쿠키 포함시 필요
- Access-Control-Allow-Methods: 허용할 HTTP 메서드
- Access-Control-Allow-Headers: 허용할 요청 헤더
- Access-Control-Expose-Headers: 클라이언트에서 접근 가능한 응답 헤더
6. 요약 체크리스트
- GET/POST(폼형식)/HEAD만 → Access-Control-Allow-Origin만 설정하면 끝.
- PUT/DELETE/PATCH/JSON/Authorization 등 → 프리플라이트 처리 필수
- 프리플라이트(OPTIONS) 응답에는 반드시 허용 헤더와 메서드 명시.
- 개발에서는 Origin을 http://localhost:8080으로 제한, 운영에서는 정확히 필요한 도메인만 허용.
7. Nginx 설정 최소 예시
단순 요청만 처리할 때:
add_header Access-Control-Allow-Origin "<http://localhost:8080>" always;
프리플라이트까지 처리할 때:
add_header Access-Control-Allow-Origin "<http://localhost:8080>" always;
add_header Access-Control-Allow-Credentials "true" always;
add_header Access-Control-Allow-Methods "GET,POST,PUT,DELETE,OPTIONS" always;
add_header Access-Control-Allow-Headers "Content-Type, Authorization" always;
if ($request_method = OPTIONS) {
return 204;
}728x90
'Etc' 카테고리의 다른 글
| Jenkins Pipline, Gitlab, SSH를 이용한 자동화 배포 방법 (1) | 2024.10.24 |
|---|---|
| [Onedrive] 다운로드, 동기화, 업로드 오류 (2) | 2024.10.08 |
| Elasticsearch, kibana 설치 및 연동(Zip) (0) | 2024.03.20 |
| AI를 통한 웹 페이지 만들기 (make real tldraw) (2) | 2023.11.28 |