Spring Security / / 2024. 10. 31. 16:27

CORS(Cross-Origin Resource Sharing)의 Simple Request와 Non-Simple Request

CORS(Cross-Origin Resource Sharing)는 웹 페이지가 다른 도메인의 리소스에 접근할 때 보안을 위해 특정 규칙을 적용하는 방식입니다. 이때 요청은 Simple Request(단순 요청)과 Non-Simple Request(비단순 요청)으로 나뉩니다.

 

1. Simple Request (단순 요청)

 

단순 요청은 브라우저에서 서버에 사전 요청(preflight) 없이 바로 요청을 보낼 수 있는 CORS 요청 유형입니다. 사전 요청이 없기 때문에 네트워크 자원이 절약되고, 단순한 API 호출이나 기본 리소스 접근에 사용됩니다.

 

Simple Request의 조건

 

1. 허용된 HTTP 메서드:

GET

POST

HEAD

2. 허용된 요청 헤더:

추가적인 사용자 정의 헤더를 사용할 수 없으며, 아래 헤더만 허용됩니다:

Accept

Accept-Language

Content-Language

Content-Type (단, 특정 값만 허용됨)

3. 허용된 Content-Type 값:

Content-Type 헤더의 값이 아래 중 하나여야 합니다:

text/plain

multipart/form-data

application/x-www-form-urlencoded

 

이 세 가지 조건 중 하나라도 충족하지 않으면 요청은 비단순 요청으로 간주됩니다.

 

Simple Request의 예시

 

예시 1: GET 요청

 

다음 GET 요청은 Simple Request에 해당하며, 사전 요청 없이 서버에 접근합니다.

fetch("https://api.example.com/data", {
    method: "GET",
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error(error));

 

예시 2: POST 요청 (Content-Type: application/x-www-form-urlencoded)

fetch("https://api.example.com/submit", {
    method: "POST",
    headers: {
        "Content-Type": "application/x-www-form-urlencoded",
    },
    body: "key1=value1&key2=value2"
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error(error));

 

위 요청은 조건을 충족하기 때문에 사전 요청 없이 바로 서버에 전달됩니다.

 

2. Non-Simple Request (비단순 요청)

 

Non-Simple Request는 단순 요청의 조건을 충족하지 않는 모든 요청입니다. HTTP 메서드가 PUT, DELETE, PATCH 단순 요청에 해당하지 않는 경우이거나, 허용되지 않은 헤더가 포함된 요청은 비단순 요청으로 처리됩니다.

 

Non-Simple Request의 조건

 

1. 허용되지 않은 HTTP 메서드 사용:

PUT, DELETE, PATCH, OPTIONS, 등 단순 요청에 포함되지 않은 메서드를 사용할 경우

2. 허용되지 않은 헤더 포함:

사용자 정의 헤더나 인증 관련 헤더(Authorization 등)가 포함된 경우

3. 허용되지 않은 Content-Type 값 사용:

application/json, application/xml, text/xml 등 단순 요청에서 허용되지 않은 Content-Type 값이 포함된 경우

 

Non-Simple Request의 사전 요청 (Preflight Request)

 

비단순 요청을 보내기 전에, 브라우저는 **사전 요청(preflight request)**이라는 OPTIONS 메서드를 서버에 먼저 보냅니다. 서버는 이 사전 요청을 통해 클라이언트가 보낸 본 요청을 허용할지 결정합니다.

 

사전 요청에는 HTTP 메서드헤더 등 본 요청의 정보를 포함하여 서버가 허용 여부를 판단할 수 있도록 합니다.

서버는 사전 요청에 대해 Access-Control-Allow-Methods, Access-Control-Allow-Headers, Access-Control-Allow-Origin 등의 헤더로 응답하며, 이를 통해 본 요청 허용 여부를 클라이언트에 전달합니다.

 

예시 1: 사전 요청 후 본 요청

 

1. 사전 요청 (OPTIONS):

OPTIONS 메서드로 Authorization 헤더가 포함된 POST 요청을 보내기 전, 사전 요청을 먼저 보냅니다.

OPTIONS /secure-data HTTP/1.1
Host: api.example.com
Access-Control-Request-Method: POST
Access-Control-Request-Headers: Authorization
Origin: https://client.example.com

 

2. 서버 응답 (허용하는 경우):

서버가 응답으로 요청을 허용하는 헤더를 설정합니다.

HTTP/1.1 204 No Content
Access-Control-Allow-Origin: https://client.example.com
Access-Control-Allow-Methods: POST
Access-Control-Allow-Headers: Authorization

 

3. 본 요청:

서버가 사전 요청을 허용했다면, 이제 클라이언트는 본 요청을 POST로 보내며 Authorization 헤더를 포함할 수 있습니다.

fetch("https://api.example.com/secure-data", {
    method: "POST",
    headers: {
        "Authorization": "Bearer token",
        "Content-Type": "application/json"
    },
    body: JSON.stringify({ key: "value" })
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error(error));

 

CORS 요청 요약

CORS Simple Request vs. Non-Simple Request 요약

요청 유형 조건 사전 요청 필요 여부
Simple Request (단순 요청)
  • HTTP 메서드: GET, POST, HEAD만 허용
  • 허용된 헤더: Accept, Accept-Language, Content-Language, Content-Type (단, text/plain, multipart/form-data, application/x-www-form-urlencoded만 허용)
  • 사용자 정의 헤더(custom headers) 없음
아니요
Non-Simple Request (비단순 요청)
  • HTTP 메서드: PUT, DELETE, PATCH 등 단순 요청이 아닌 메서드
  • 사용자 정의 헤더 포함 (예: Authorization)
  • 허용되지 않은 Content-Type 사용 (예: application/json)

참고: Simple Request는 서버에 직접 요청할 수 있지만, Non-Simple Request는 서버 권한 확인을 위한 사전 요청(OPTIONS)이 필요합니다.

 

이렇게 CORS는 클라이언트가 다른 출처의 리소스에 접근할 때 서버에서 명시적으로 허용하는 경우에만 접근을 허용하도록 해 보안을 강화하고 있습니다.

'Spring Security' 카테고리의 다른 글

RFC6265  (0) 2024.10.31
SameSite  (0) 2024.10.31
Spring Security 인증 아키텍처  (0) 2024.10.31
FilterOrderRegistration 클래스 구조와 역할  (0) 2024.10.31
requestMatcher  (0) 2024.10.30
  • 네이버 블로그 공유
  • 네이버 밴드 공유
  • 페이스북 공유
  • 카카오스토리 공유