2023. 6. 20. 15:35ㆍSpring Security
📌 CORS: Simple Request와 Non-Simple Request의 차이점
1. CORS란? 🛡️
CORS(Cross-Origin Resource Sharing)는 웹 애플리케이션이 다른 출처(origin)에서 리소스를 요청할 수 있도록 허용하는 보안 메커니즘입니다. 보안 정책의 일환으로, 브라우저는 동일 출처 정책(Same-Origin Policy)을 디폴트로 적용하지만, 특정 조건을 충족하면 교차 출처 요청을 허용할 수 있습니다.
CORS는 서버가 특정 출처에서 오는 요청을 허용할지 결정하는데, 이때 Simple Request(단순 요청)과 Non-Simple Request(비단순 요청)을 구분하여 다르게 처리합니다. 🚀
2. Simple Request(단순 요청) 🟢
✅ Simple Request란?
Simple Request는 브라우저가 사전 요청(Preflight 요청, OPTIONS 요청)을 수행하지 않고 직접 서버에 요청을 보낼 수 있는 요청을 의미합니다.
이 요청이 단순한지 판단하는 기준은 다음과 같습니다:
📌 Simple Request의 조건
- HTTP 메소드 제한
- 요청의 메소드는 GET, POST, HEAD 중 하나여야 합니다.
- Content-Type 제한
- 요청의
Content-Type
이 다음 값 중 하나여야 합니다:application/x-www-form-urlencoded
multipart/form-data
text/plain
- 즉,
application/json
같은 Content-Type은 단순 요청이 아닙니다. ❌
- 요청의
- 사용자 정의 헤더 없음
Authorization
,X-Custom-Header
등 브라우저가 기본적으로 제공하지 않는 사용자 정의 헤더를 포함하면 안 됩니다.- 기본적인
Accept
,Content-Type
,User-Agent
등만 허용됩니다.
✅ Simple Request의 예시
1️⃣ GET 요청 (단순 요청 ✅)
GET /api/data HTTP/1.1
Host: server.com
Origin: https://client.com
2️⃣ POST 요청 (Content-Type이 application/x-www-form-urlencoded
인 경우 ✅)
POST /api/data HTTP/1.1
Host: server.com
Origin: https://client.com
Content-Type: application/x-www-form-urlencoded
key1=value1&key2=value2
이러한 요청은 브라우저가 사전 요청(Preflight Request)을 보내지 않고 바로 서버에 요청을 보냅니다.
✅ Simple Request의 서버 응답
서버는 단순 요청을 허용할 경우, 다음과 같은 응답을 반환해야 합니다:
HTTP/1.1 200 OK
Access-Control-Allow-Origin: https://client.com
Content-Type: application/json
{"message": "Hello, World!"}
3. Non-Simple Request(비단순 요청) 🔴
❌ Non-Simple Request란?
Non-Simple Request(비단순 요청)는 브라우저가 보안상의 이유로 Preflight 요청(OPTIONS 요청)을 먼저 보내서 서버의 허용 여부를 확인해야 하는 요청입니다. 즉, 서버가 해당 요청을 수락할지 사전에 확인하는 과정이 필요합니다. ⚠️
📌 Non-Simple Request의 조건
아래 세 가지 조건 중 하나라도 위반하면 비단순 요청이 됩니다:
- 허용되지 않은 HTTP 메소드 사용
- GET, POST, HEAD 이외의 HTTP 메소드를 사용할 경우
- 예:
PUT
,DELETE
,PATCH
,OPTIONS
- 허용되지 않은 Content-Type 사용
application/json
같은Content-Type
을 사용할 경우
- 사용자 정의 헤더 포함
X-Custom-Header
,Authorization
,X-Requested-With
등의 헤더가 포함될 경우
❌ Non-Simple Request의 예시
1️⃣ PUT 요청 (비단순 요청 🚨)
PUT /api/resource HTTP/1.1
Host: server.com
Origin: https://client.com
Content-Type: application/json
{"key": "value"}
2️⃣ 사용자 정의 헤더 포함 요청 (비단순 요청 🚨)
POST /api/resource HTTP/1.1
Host: server.com
Origin: https://client.com
Content-Type: application/x-www-form-urlencoded
X-Custom-Header: CustomValue
key1=value1&key2=value2
🔄 Preflight 요청(OPTIONS 요청)이 필요한 이유
위와 같은 비단순 요청이 발생하면, 브라우저는 먼저 Preflight 요청을 보내서 서버가 해당 요청을 허용하는지 확인합니다.
📌 Preflight 요청 예시 (OPTIONS 메소드 사용)
OPTIONS /api/resource HTTP/1.1
Host: server.com
Origin: https://client.com
Access-Control-Request-Method: PUT
Access-Control-Request-Headers: Content-Type
✅ 서버의 Preflight 응답
서버는 다음과 같은 응답을 반환하여 요청을 허용할 수 있습니다:
HTTP/1.1 204 No Content
Access-Control-Allow-Origin: https://client.com
Access-Control-Allow-Methods: PUT, POST, DELETE
Access-Control-Allow-Headers: Content-Type, X-Custom-Header
이 응답을 받은 후, 브라우저는 실제 요청을 서버에 전송합니다. 🎯
4. CORS 정책 설정하기 🛠️
CORS를 올바르게 설정하지 않으면 브라우저에서 요청이 차단될 수 있습니다. 따라서, 서버에서 올바르게 CORS 정책을 설정해야 합니다.
✅ Spring Boot에서 CORS 설정 (Java)
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class WebConfig {
@Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurer() {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("https://client.com")
.allowedMethods("GET", "POST", "PUT", "DELETE")
.allowedHeaders("Content-Type", "Authorization");
}
};
}
}
✅ Express.js에서 CORS 설정 (Node.js)
const express = require('express');
const cors = require('cors');
const app = express();
app.use(cors({
origin: 'https://client.com',
methods: ['GET', 'POST', 'PUT', 'DELETE'],
allowedHeaders: ['Content-Type', 'Authorization']
}));
5. 결론 🎯
✅ Simple Request는 추가적인 보안 검증 없이 바로 요청할 수 있는 경우이며, Non-Simple Request는 보안 검증을 위해 Preflight 요청이 필요한 경우입니다.
📌 올바른 CORS 정책을 설정하면, 브라우저에서의 요청 차단을 방지하고 보안성을 유지하면서도 원활한 API 통신을 가능하게 할 수 있습니다! 🚀
'Spring Security' 카테고리의 다른 글
ch03 Managing users (0) | 2024.02.25 |
---|---|
Ch02 Hello Spring Security (0) | 2024.02.25 |
Options (0) | 2023.06.10 |
CSRF (0) | 2023.06.08 |
Jason Web Token (0) | 2023.04.17 |