CORS(Cross Origin Resource Sharing) 개념
- 출처 교차(Cross Origin): 리소스를 주고받는 곳의 출처가 다른 경우에 발생함 (*출처: 도메인, 프로토콜, 포트 등)
- 출처 교차인 경우 접근 권한을 부여하는 메커니즘이 필요함
- CORS는 서로 다른 출처에서 제공되는 리소스에 접근할 수 있도록 허용하는 정책
CORS의 필요성?
- 위조 요청 문제를 해결하기 위함(CSRF, Cross-Site Request Forgery, 크로스사이트 요청 위조)
- 피해자가 공격자의 웹 사이트에 접속했을 때, 해당 사용자의 요청인 것처럼 타 사이트에 GET 요청을 보냄
- 위와 같이 의도치 않은 요청을 서버에 보내서, 사용자의 개인정보 등을 탈취할 수 있음.
SOP란?
- Same-origin policy: 동일 출처 정책. 클라이언트와 동일한 출처의 리소스로만 요청을 보낼 수 있음
- 다른 출처의 요청을 보낼 경우, 해당 요청에 대한 응답에 접근할 수 없도록 막음. CSRF 공격 효과 줄이고 보안을 강화함.
- But! 합법적인 요청까지 차단될 수 있음. 현대의 웹 어플리케이션은 다른 출처의 리소스를 사용하는 경우가 많음.
CORS 작동 과정?
1. Simple Request
🔹 방법: 브라우저 요청 메시지에 Origin 헤더와 응답 메시지의 Access-Controll-Allow-Origin 헤더를 비교함
- Origin: 현재 요청하는 클라이언트의 출처
- Access-Control-Allow-Origin: 리소스 요청 허용하는 출처
🔹 해당하는 경우
- 요청 메서드
GET, POST HEAD인 경우만 - 수동으로 설정한 요청 헤더
Accept, Accept-Language, Content-Language, Content-Type, Range인 경우만 - Content-Type 헤더
application/x-www-form-urlencoded, multipart/form-data, text/plain인 경우만(헤더가 단순해야 함)
🔹 예시
- 요청
GET /api/data HTTP/1.1
Host: example.com
Origin: http://my-client.com - 응답
HTTP/1.1 200 OK
Access-Control-Allow-Origin: http://my-client.com
Content-Type: application/json
http://my-client.com
my-client.com
2. Preflight Request: 브라우저가 사전 요청을 보내는 경우
🔹 방법:
브라우저 본 요청을 보내기 전에 Preflight Request를 OPTIONS 메서드로 요청. 실제 요청이 안전한지 검토
🔹 해당하는 경우
- 요청 메서드(Access-Control-Request-Method)
PUT, DELET, PATCH 등(요청 메서드가 GET, POST, HEAD 아닌 경우) - Custom Header를 사용하는 경우 (Access-Control-Reques-Headers)
Authorization, X-Custom-Header 등 사용자가 추가한 헤더가 요청에 포함될 때 - Content-Type 헤더가 단순하지 않은 경우
application/json, text/xml 등 단순하지 않은 MIME 타입을 사용할 때
🔹 예시
- 요청
OPTIONS /api/resource HTTP/1.1
Host: example.com
Origin: http://my-client.com (허용된 Origin)
Access-Control-Request-Method: DELETE (허용된 메서드)
Access-Control-Request-Headers: X-Custom-Header(허용된 요청 헤더)
Access-Control-Max-Age: - 응답
HTTP/1.1 204 No Content
Access-Control-Allow-Origin: http://my-client.com (허용된 Origin)
Access-Control-Allow-Method: GET, POST, DELETE (허용된 Method)
Access-Control-Allow-Header: X-Custom-Header (허용된 사용자 정의 헤더)
Access-Control-Max-Age: 86400(결과 캐싱 기간)
서버 요청이 성공했지만, Preflight는 서버/브라우저 간의 협상 단계라서 실제 데이터 반환하지 않음.
3. Credential Request: 인증된 요청을 사용(쿠키, 인증 토큰 등)
🔹 방법: 클라이언트가 서버에 요청을 보낼 때 쿠키나 인증 토큰 같은 사용자 인증 정보를 포함
🔹 해당하는 경우
- 클라이언트->
서버 요청 시 credentials 옵션을 설정함 - 서버->
클라이언트 응답 시 Access-Control-Allow-Credentials:true 헤더 포함.
Access-Control-Allow-Origin에 특정 Origin 명시
(와일드 카드 * 사용 불가. 모든 Origin 허용같은 설정이 불가능하다는 뜻)
🔹 예시
- 요청
fetch("https://example.com/api", { method:"GET", credentials:"include",}); - 응답
HTTP/1.1 200 OK
Access-Control-Allow-Origin: http://my-client.com
Access-Control-Allow-Credentials: true
Simple Request | Preflight Request | Credential Request | |
방법 | 요청 헤더 출처와 응답 헤더 허용 출처를 비교함 | 본 요청 전에 OPTIONS 메서드로 요청해서 허용된 출처인지 확인함 | 인증된 요청을 사용함(쿠키, 토큰 등) |
메서드 | GET, POST, HEAD | PUT, DELETE, PATCH | |
헤더 | Accept Accept-Language Content-Language Content-Type Range |
커스텀 헤더 사용 Authorization, X-Custom-Header |
credentials 옵션 설정 |
Content-Type 헤더 | application/x-www-form-urlencoded multipart/form-data text/plain |
복잡한 헤더 application/json text/xml |
|
기타 | 가장 간단한 방법 | 본 요청 전 사전 요청이라 콘텐츠 미포함 |
와일드 카드 안됨. 정확한 Origin 명시. |
출처
[1] 매일메일 250118 CORS란 무엇인가요? https://maeil-mail.kr 96번
매일메일 - 기술 면접 질문 구독 서비스
기술 면접 질문을 매일매일 메일로 보내드릴게요!
www.maeil-mail.kr
[2] gpt에게 preflight request, credential request, simple request에 대해 묻다
[3] 매일메일. 250205. CORS는 무엇이며 왜 필요한가요? 78번 https://maeil-mail.kr
[4] 토스 페이먼츠. CORS(교차 출처 리소스 공유) https://docs.tosspayments.com/resources/glossary/cors
'개발자 강화 > 백엔드' 카테고리의 다른 글
[매일메일] ACID란? (BE.250207) (0) | 2025.02.08 |
---|---|
[매일메일] 동시성 제어(BE.250114/250115/250205/250106 통합) (0) | 2025.02.06 |
[매일메일] 로드 밸런싱이란? (BE.250203) (0) | 2025.02.03 |
[매일메일] 다중 서버에서 세션 기반 인증을 사용했을 때 문제점? (BE.250131) (0) | 2025.01.31 |
[매일메일] SOLID 원칙이란? (BE.250130) (0) | 2025.01.30 |