1. CORS란 무엇인가요?
CORS(Cross-Origin Resource Sharing)는 웹 브라우저에서 실행 중인 웹 애플리케이션이 다른 출처(도메인, 프로토콜, 포트)의 리소스에 접근할 수 있도록 하는 메커니즘입니다. 브라우저는 기본적으로 보안상의 이유로 다른 출처에 대한 HTTP 요청을 제한하는데, 이것을 '동일 출처 정책(Same-Origin Policy)'이라고 합니다.
예를 들어, http://localhost:3000
에서 실행 중인 React 애플리케이션이 http://localhost:8080
에서 실행 중인 Spring Boot API에 데이터를 요청할 때 CORS 제한이 발생합니다.
2. 왜 CORS 설정이 필요한가요?
현대 웹 개발 환경에서는 프론트엔드(React, Vue, Angular 등)와 백엔드(Spring Boot, Node.js 등)를 분리하여 개발하는 것이 일반적입니다. 이런 경우 프론트엔드와 백엔드는 서로 다른 출처에서 실행되기 때문에 CORS 설정이 필수적입니다.
CORS 설정이 없으면 다음과 같은 오류가 발생합니다:
Access to XMLHttpRequest at 'http://localhost:8080/api/data' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
3. Spring Boot에서 CORS 설정하기
Spring Boot에서 CORS를 설정하는 방법은 여러 가지가 있지만, 가장 일반적인 방법은 WebMvcConfigurer
인터페이스를 구현하는 설정 클래스를 만드는 것입니다.
WebConfig 클래스 설명
package com.example.reactTe.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
/**
* CORS 설정을 위한 Web 설정 클래스
*/
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/api/**") // 어떤 API 경로에 CORS 설정을 적용할지 지정
.allowedOrigins("http://localhost:3000") // 어떤 출처에서 오는 요청을 허용할지 지정
.allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS") // 허용할 HTTP 메소드 지정
.allowedHeaders("*") // 허용할 HTTP 헤더 지정
.allowCredentials(true); // 인증 정보(쿠키, JWT 등) 포함 허용
}
}
4. CORS 설정 옵션 상세 설명
4.1 addMapping(String pathPattern)
- 특정 API 경로 패턴에 CORS 설정을 적용합니다.
- 예:
/api/**
는 /api로 시작하는 모든 경로에 CORS 설정을 적용합니다. - 특정 경로만 적용하려면:
/api/users/**
와 같이 지정할 수 있습니다.
4.2 allowedOrigins(String... origins)
- 허용할 출처(도메인)을 지정합니다.
- 예:
http://localhost:3000
은 이 도메인에서 오는 요청만 허용합니다. - 여러 출처를 허용하려면:
.allowedOrigins("http://localhost:3000", "https://myapp.com")
- 모든 출처를 허용하려면(권장하지 않음):
.allowedOrigins("*")
- 동적으로 출처를 결정하려면:
.allowedOriginPatterns("*")
4.3 allowedMethods(String... methods)
- 허용할 HTTP 메소드를 지정합니다.
- 일반적으로 필요한 메소드는 "GET", "POST", "PUT", "DELETE", "OPTIONS"입니다.
- REST API를 개발할 때는 모든 메소드가 필요합니다.
- "OPTIONS"는 사전 요청(preflight request)을 처리하기 위해 필요합니다.
4.4 allowedHeaders(String... headers)
- 허용할 HTTP 헤더를 지정합니다.
"*"
는 모든 헤더를 허용합니다.- 특정 헤더만 허용하려면:
.allowedHeaders("Content-Type", "Authorization")
4.5 allowCredentials(boolean allowCredentials)
- 브라우저가 요청에 인증 정보(쿠키, HTTP 인증, 클라이언트 측 SSL 인증서 등)를 포함할 수 있는지 여부를 결정합니다.
true
로 설정하면 인증 정보를 포함한 요청이 허용됩니다.- JWT 토큰 기반 인증 등을 사용할 때 필요합니다.
- 주의:
allowCredentials(true)
와allowedOrigins("*")
는 함께 사용할 수 없습니다.
4.6 maxAge(long maxAge)
- 사전 요청(preflight request)의 결과를 캐시할 시간(초)을 지정합니다.
- 캐싱을 통해 불필요한 사전 요청을 줄일 수 있습니다.
- 예:
.maxAge(3600)
// 1시간 동안 캐시
5. 다양한 CORS 설정 예시
5.1 기본 설정 (특정 도메인만 허용)
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/api/**")
.allowedOrigins("http://localhost:3000")
.allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
.allowedHeaders("*")
.allowCredentials(true);
}
5.2 다중 출처 허용
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/api/**")
.allowedOrigins(
"http://localhost:3000",
"https://my-production-app.com"
)
.allowedMethods("*")
.allowedHeaders("*")
.allowCredentials(true);
}
5.3 특정 API 경로에 다른 CORS 설정 적용
@Override
public void addCorsMappings(CorsRegistry registry) {
// 공개 API
registry.addMapping("/api/public/**")
.allowedOrigins("*")
.allowedMethods("GET")
.allowedHeaders("*");
// 인증이 필요한 API
registry.addMapping("/api/auth/**")
.allowedOrigins("http://localhost:3000")
.allowedMethods("*")
.allowedHeaders("*")
.allowCredentials(true)
.maxAge(3600);
}
5.4 프로덕션 환경을 위한 동적 CORS 설정
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Value("${cors.allowed-origins}")
private String[] allowedOrigins;
@Value("${cors.allowed-methods:GET,POST,PUT,DELETE,OPTIONS}")
private String[] allowedMethods;
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/api/**")
.allowedOrigins(allowedOrigins)
.allowedMethods(allowedMethods)
.allowedHeaders("*")
.allowCredentials(true)
.maxAge(3600);
}
}
application.properties 또는 application.yml 파일:
# 개발 환경
cors.allowed-origins=http://localhost:3000,http://localhost:8000
# 프로덕션 환경
# cors.allowed-origins=https://my-production-app.com
6. CORS 문제 해결 및 디버깅 팁
6.1 일반적인 CORS 오류 메시지 및 해결 방법
"No 'Access-Control-Allow-Origin' header is present"
- 문제: 서버에서 Access-Control-Allow-Origin 헤더를 설정하지 않았습니다.
- 해결: allowedOrigins()를 올바르게 설정했는지 확인하세요.
"The value of the 'Access-Control-Allow-Origin' header ... does not match the supplied origin"
- 문제: 요청한 출처가 allowedOrigins()에 포함되어 있지 않습니다.
- 해결: allowedOrigins()에 해당 출처를 추가하세요.
"Method XXX is not allowed by Access-Control-Allow-Methods"
- 문제: 요청한 HTTP 메소드가 허용되지 않았습니다.
- 해결: allowedMethods()에 해당 메소드를 추가하세요.
"Credential is not supported if the CORS header 'Access-Control-Allow-Origin' is '*'"
- 문제: allowCredentials(true)와 allowedOrigins("*")를 함께 사용했습니다.
- 해결: 특정 출처를 명시적으로 지정하세요.
6.2 브라우저 개발자 도구를 이용한 디버깅
- 브라우저의 개발자 도구를 엽니다 (F12 또는 우클릭 후 '검사' 선택).
- 네트워크 탭에서 API 요청을 확인합니다.
- CORS 오류가 발생한 요청을 클릭합니다.
- 응답 헤더에 적절한 CORS 헤더가 포함되어 있는지 확인합니다:
- Access-Control-Allow-Origin
- Access-Control-Allow-Methods
- Access-Control-Allow-Headers
- Access-Control-Allow-Credentials
7. 요약 및 모범 사례
- 보안을 고려하세요: 꼭 필요한 출처와 메소드만 허용하세요.
- 와일드카드 사용을 자제하세요:
allowedOrigins("*")
는 프로덕션 환경에서 사용하지 마세요. - 환경별 설정을 활용하세요: 개발, 테스트, 프로덕션 환경에 맞게 CORS 설정을 분리하세요.
- 사전 요청(Preflight) 캐싱을 활용하세요: maxAge()를 설정하여 성능을 개선하세요.
- 오류 메시지를 주의 깊게 읽으세요: CORS 오류 메시지는 문제의 원인을 파악하는 데 도움이 됩니다.
Spring Boot에서 CORS를 올바르게 설정하면 프론트엔드와 백엔드 간의 원활한 통신이 가능해져 더 나은 사용자 경험을 제공할 수 있습니다. 이 글이 여러분의 CORS 이해와 설정에 도움이 되었길 바랍니다!
'개발일지 > React' 카테고리의 다른 글
"React 훅(Hooks) 10개 완벽 가이드: React 19 버전 기준" (0) | 2025.03.06 |
---|---|
2025년 React.js: 프론트엔드 개발의 중심과 그 중요성 (0) | 2025.03.06 |
Create React App 사용법 가이드 (0) | 2025.03.06 |
ReactJS에서 useEffect 훅 완벽 이해하기 (0) | 2025.03.06 |
React 앱을 GitHub Pages에 배포하는 완벽 가이드: 최신 방법과 팁 (1) | 2025.03.05 |
댓글