SOP 정책을 위반해도 CORS 정책을 따르면 다른 출처의 리소스라도 허용한다.
1. SOP(Same Origin Policy)
SOP는 직역하면 동일 출처 정책 입니다. 도통 무슨 소리인지 감을 잡을 수 없죠
이 의미를 알려면 먼저 Origin(출처)에 대해서 알아보아야합니다.
Origin이란 URL 구성 요소에서 |
Scheme + Hostname + Port 부분을 뜻합니다. |
SOP란 이런 Origin의 동일성과 관련된 정책이라는 의미를 내포하고 있겠죠! |
즉, 동일하지 않은 출처의 자원을 허용하지 않는 정책입니다. |
브라우저는 최초의 정적 파일을 렌더링한 Web Server(http:daon-world.com)를 Origin으로 정의합니다.
다음 요청에서 브라우저가 API Server(Origin : http://jjolba-escape.kr)로 요청을 하게 되면
이는 동일 출처의 자원만 사용 가능하다는 SOP 정책을 위반하게 됩니다.
이 때 브라우저는 CORS 에러를 뱉게 됩니다.
2. CORS(Cross Origin Resosurce Sharing)
CORS는 API 서버의 설정에서 요청한 출처(웹 서버)가 허용된 출처임을 명시하는 기능입니다. |
이를 통해 요청과 응답이 서로 다른 Origin을 갖고 있어도 SOP(동일 출처 정책)를 위반을 허용하는 설정입니다. |
즉, SOP의 예외 조항에 해당하는 설정이라고 할 수 있습니다. |
- 브라우저(Client)는 요청 시 Request Header에 Origin 정보를 담아 보냅니다.
- Server는 헤더에 해당 리소스에 접근하는 것이 허용된 출처 Origin을 Access-Control-Allow-Origin에 담아 보냅니다.
- 브라우저는 요청 헤더의 Origin, 응답 헤더의 Access-Control-Allow-Origin을 비교합니다.
- 동일한 경우 다른 출처의 리소스를 허용하고,
- 다를 경우 브라우저는 CORS 에러를 내뱉습니다.
3. CORS 시나리오
앞으로 소개할 시나리오들을 테스트 해볼 수 있는 아주 좋은 사이트가 있어서 소개합니다.
https://chuckchoiboi.github.io/cors-tutorial/
CORS Tutorial
chuckchoiboi.github.io
사전 요청(Preflight Request)
CORS 에러는 서버가 아니라 브라우저가 내뱉는 것입니다.
그래서 서버는 브라우저가 CORS를 내뱉기 전 실제 데이터를 처리하게 되는데요
이를 방지하기 위해 사전에 안전한 요청을 보내 Origin이 같은지 판단 후 본 요청을 보내게 됩니다.
사전 요청에서는 서버에 아무런 영향도 미치지 않는 HTTP method인 OPTIONS 으로 요청을 보내고
앞서 설명한 바와 같이 요청 헤더의 Origin, 응답 헤더의 Access-Control-Allow-Origin의 값을 비교하여 허용 여부를 결정합니다.
(* 는 모든 출처 허용을 뜻하는 와일드 카드입니다.)
단순 요청 (Simple Request)
단순 요청은 사전 요청처럼 사전에 안전한 요청으로 확인하는 단계 없이 바로 본 요청을 보냅니다.
단순 요청이 이루어질 수 있는 조건들은 다음과 같습니다.(매우 까다롭... 그래서 거의 Preflight Request 요청이 사용된다.
- 요청의 메소드는 GET, HEAD, POST 중 하나여야 한다.
- Accept, Accept-Language, Content-Language, Content-Type, DPR, Downlink, Save-Data, Viewport-Width, Width 헤더일 경우 에만 적용된다.
- Content-Type 헤더가 application/x-www-form-urlencoded, multipart/form-data, text/plain중 하나여야한다. 아닐 경우 예비 요청으로 동작된다.
인증된 요청 (Credentialed Request)
인증된 요청은 사전 요청의 흐름과 요청을 판단하는 근거도 같습니다.
차이점으로는
- 요청에 쿠기 값이 들어갈 수 있고,
- 응답 헤더의 Access-Control-Allow-Origin에 와일드 카드(*)를 사용할 수 없습니다.
- 또한 서버는 Access-Control-Allow-Credentials를 반드시 true로 설정해 요청 출처가 인증 관련된 정보를 갖는 출처임을 명시해야합니다.
앞단 요청 예시
브라우저의 요청 API들은 credentials 옵션을 설정해 줘야만 브라우저의 쿠키 같은 인증 관련 데이터를 요청 데이터에 담을 수 있다.
credentials 옵션의 값으로 사용될 수 있는 값들은 다음과 같습니다.
옵션 값 | 설명 |
same-origin | 같은 출처 간 요청에만 인증 정보 보내기 허용 |
include | 모든 요청에 인증 정보 보내기 허용 |
omit | 모든 요청에 인증 정보 보내기 불허용 |
credentails 옵션 설정 문법은 요청 API 마다 다릅니다.
// fetch 메서드
fetch("https://example.com:1234/users/login", {
method: "POST",
credentials: "include", // 클라이언트와 서버가 통신할때 쿠키와 같은 인증 정보 값을 공유하겠다는 설정
body: JSON.stringify({
userId: 1,
}),
})
뒷단 응답 예시 (Spring)
@Configuration
public Class Corsconfig implements WebMvcConfigurer{
@Override
public void addCorsMappings(CorsRegistry corsRegistry){
regist.addMapping("/**")
.allowedOrigins("[허용할 출처 Origin]")
.allowCredentials(true);
}
}
WebMvcConfigurer을 implements하고 |
addCorsMappings 메서드를 오버라이드하여 CORS 설정을 합니다. |
addMapping : CORS을 적용할 Path (/**는 모든 Path를 뜻함) 설정 |
allowdOrigins : 접근을 허용할 출처 Origin 설정 |
allowCredentials : 인증정보를 담는 요청 여부 설정 |
출처
'Programming > Server' 카테고리의 다른 글
[Server] ~/.bashrc (0) | 2025.01.09 |
---|---|
[Server]Jboss (0) | 2024.12.10 |
[Server] 빌드와 배포 (0) | 2024.09.29 |
[Server] Docker란? (1) | 2024.09.19 |
[Server] WebServer와 Web Application Server (WAS) (1) | 2024.09.14 |