on my way
CORS란? 필요성, 작동 방식 및 어노테이션 예제 본문
]
CORS(Cross-Origin Resource Sharing)는 웹 브라우저에서 다른 출처(도메인, 프로토콜, 포트)의 리소스에 접근할 수 있도록 허용하는 보안 기능입니다. 기본적으로 웹 브라우저는 보안상의 이유로 동일 출처 정책(Same-Origin Policy)을 따르며, 이 정책은 다른 출처에서 리소스를 요청하는 것을 제한합니다. CORS는 이러한 제한을 완화하여 특정 조건 하에 다른 출처의 리소스에 접근할 수 있도록 합니다.
CORS의 필요성
웹 애플리케이션은 종종 다른 도메인의 리소스에 접근해야 하는 경우가 있습니다. 예를 들어, example.com 도메인에서 실행되는 웹 애플리케이션이 api.example.com 도메인에 있는 API에 요청을 보내는 경우입니다. 동일 출처 정책에 따르면, 이러한 요청은 기본적으로 차단됩니다. CORS를 사용하면 서버가 특정 출처에서 오는 요청을 허용하도록 설정할 수 있습니다.
CORS의 작동 방식
CORS는 HTTP 헤더를 사용하여 작동합니다. 브라우저는 서버에 요청을 보낼 때 CORS 관련 헤더를 포함시킵니다. 서버는 해당 요청을 허용할지 여부를 결정하고, 응답 헤더를 통해 브라우저에 이를 알립니다.
주요 CORS 헤더
- Access-Control-Allow-Origin
- 서버가 특정 출처에서의 요청을 허용할 때 사용합니다.
- 예: Access-Control-Allow-Origin: https://example.com
- 모든 출처를 허용하려면 *를 사용할 수 있습니다.
- Access-Control-Allow-Methods
- 허용되는 HTTP 메소드를 지정합니다.
- 예: Access-Control-Allow-Methods: GET, POST, PUT
- Access-Control-Allow-Headers
- 허용되는 HTTP 헤더를 지정합니다.
- 예: Access-Control-Allow-Headers: Content-Type, Authorization
- Access-Control-Allow-Credentials
- 자격 증명을 포함한 요청을 허용할지 여부를 지정합니다.
- 예: Access-Control-Allow-Credentials: true
- Access-Control-Max-Age
- 프리플라이트(preflight) 요청의 결과를 캐시할 시간을 지정합니다.
- 예: Access-Control-Max-Age: 3600
프리플라이트 요청
CORS는 단순 요청(Simple Request)과 프리플라이트 요청(Preflight Request)으로 나뉩니다. 프리플라이트 요청은 브라우저가 실제 요청을 보내기 전에 서버에 OPTIONS 메소드를 사용하여 안전성을 확인하는 요청입니다. 이 요청을 통해 서버는 실제 요청이 허용될지 여부를 결정합니다.
단순 요청(Simple Request)
- GET, POST, HEAD 메소드 중 하나를 사용하고,
- 커스텀 헤더를 포함하지 않으며,
- Content-Type이 application/x-www-form-urlencoded, multipart/form-data, 또는 text/plain인 경우.
프리플라이트 요청(Preflight Request)
- 단순 요청이 아닌 경우,
- PUT, DELETE 등의 메소드를 사용하거나,
- 커스텀 헤더를 포함하는 경우.
예제
서버에서 CORS를 설정하는 간단한 예제는 다음과 같습니다. 예를 들어, Express.js를 사용하는 Node.js 서버에서 CORS를 설정할 수 있습니다.
javascript
const express = require('express');
const cors = require('cors');
const app = express();
app.use(cors({
origin: 'https://example.com', // 허용할 출처
methods: ['GET', 'POST'], // 허용할 메소드
allowedHeaders: ['Content-Type'], // 허용할 헤더
credentials: true // 자격 증명 허용 여부
}));
app.get('/api/data', (req, res) => {
res.json({ message: 'CORS 설정 완료' });
});
app.listen(3000, () => {
console.log('서버가 3000번 포트에서 실행 중입니다.');
});
이 예제에서는 https://example.com 출처에서 오는 GET 및 POST 요청을 허용하며, Content-Type 헤더를 허용하고, 자격 증명을 포함한 요청을 허용하도록 설정합니다.
CORS는 웹 애플리케이션의 보안과 유연성을 동시에 고려한 중요한 기능입니다. 올바르게 설정하여 적절한 출처에서의 요청을 허용하면서도 보안을 유지하는 것이 중요합니다.
Spring Framework에서는 @CrossOrigin 애노테이션을 사용하여 CORS 설정을 쉽게 적용할 수 있습니다. 이 애노테이션은 컨트롤러 클래스나 메소드 수준에서 사용할 수 있으며, 특정 출처에서 오는 요청을 허용하는 데 사용됩니다.
@CrossOrigin 애노테이션 사용 방법
클래스 수준에서 사용
클래스 수준에서 @CrossOrigin 애노테이션을 사용하면 해당 컨트롤러의 모든 엔드포인트에 대해 CORS 설정이 적용됩니다.
java
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@CrossOrigin(origins = "https://example.com")
public class MyController {
@GetMapping("/api/data")
public String getData() {
return "CORS 설정 완료";
}
}
메소드 수준에서 사용
메소드 수준에서 @CrossOrigin 애노테이션을 사용하면 해당 메소드에 대해서만 CORS 설정이 적용됩니다.
java
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class MyController {
@CrossOrigin(origins = "https://example.com")
@GetMapping("/api/data")
public String getData() {
return "CORS 설정 완료";
}
}
@CrossOrigin 애노테이션의 주요 속성
- origins: 허용할 출처(도메인)를 지정합니다. 기본값은 모든 출처(*)입니다.
- methods: 허용할 HTTP 메소드를 지정합니다. 기본값은 RequestMethod.GET입니다.
- allowedHeaders: 허용할 HTTP 헤더를 지정합니다. 기본값은 모든 헤더입니다.
- exposedHeaders: 클라이언트에 노출할 헤더를 지정합니다.
- allowCredentials: 자격 증명(쿠키, 인증 정보 등)을 포함한 요청을 허용할지 여부를 지정합니다. 기본값은 false입니다.
- maxAge: 프리플라이트 요청의 결과를 캐시할 시간(초)을 지정합니다.
예제
다양한 속성을 사용한 예제입니다.
java
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class MyController {
@CrossOrigin(
origins = "https://example.com",
methods = {RequestMethod.GET, RequestMethod.POST},
allowedHeaders = {"Content-Type", "Authorization"},
exposedHeaders = {"Custom-Header"},
allowCredentials = "true",
maxAge = 3600
)
@GetMapping("/api/data")
public String getData() {
return "CORS 설정 완료";
}
}
이 예제에서는 https://example.com 출처에서 오는 GET 및 POST 요청을 허용하며, Content-Type과 Authorization 헤더를 허용합니다. 또한, Custom-Header를 클라이언트에 노출하고, 자격 증명을 포함한 요청을 허용합니다. 프리플라이트 요청의 결과는 3600초(1시간) 동안 캐시됩니다.
'Computer Science > React' 카테고리의 다른 글
React에서 Axios를 이용한 REST API 호출 및 비동기 프로그래밍 이해하기 (0) | 2024.07.16 |
---|---|
한 입 크기로 잘라먹는 리액트 9장: 컴포넌트 트리에 데이터 공급 (0) | 2024.07.16 |
한 입 크기로 잘라먹는 리액트 8장: 최적화 (2) | 2024.07.16 |
한 입 크기로 잘라먹는 리액트 Project2: [할 일 관리] 앱 만들기 + 업데이트 (0) | 2024.07.16 |
한 입 크기로 잘라먹는 리액트 Project1: [카운터] 앱 만들기 (1) | 2024.07.16 |