꼭 필요하지만 가끔은 귀찮은 CORS 정리
프론트엔드스프링
By Jeongmin Seo•4월 20일, 2025년
목차
CORS (Cross-Origin Resource Sharing)
대부분의 개발자는 외부 API를 연동하면서 CORS 문제를 한 번쯤 겪어봤을 것이다.
CORS는 브라우저가 다른 출처(origin)의 자원에 접근할 때 보안을 위해 서버에 요청 권한을 묻는 정책이다. 동일 출처가 아닌 요청은 기본적으로 차단된다.
동일 출처(origin)란?
동일 출처란 아래 세 가지가 모두 같아야 한다:
- 프로토콜 (http, https)
- 도메인 (정민.xyz, google.com)
- 포트 (80, 443 등)
https://정민.xyz 기준 예시:
요청 URL | 동일 출처 여부 |
---|---|
https://정민.xyz/api | 동일 |
http://정민.xyz/api | 다른 프로토콜 |
http://api.정민.xyz | 다른 서브도메인 |
http://정민.xyz:3000 | 다른 포트 |
CORS 동작 방식
- 클라이언트에서 다른 origin으로 요청을 보낸다.
- 브라우저는 Preflight 요청을 먼저 보낸다.
OPTIONS
메서드로 서버에 “이 요청 허용되나요?”를 묻는다.
- 서버는
Access-Control-Allow-*
헤더를 포함하여 응답한다. - 브라우저가 허용되었다고 판단하면 실제 요청을 진행한다.
모든 요청이 Preflight 요청을 거치는 것은 아니다. 단순 GET 요청 등은 생략될 수 있다.
주요 응답 헤더
Access-Control-Allow-Origin
: 허용된 출처 (ex:https://example.com
또는*
)Access-Control-Allow-Methods
: 허용된 HTTP 메서드 (ex:GET, POST, PUT
)Access-Control-Allow-Headers
: 허용된 헤더 목록 (ex:Content-Type, Authorization
)Access-Control-Allow-Credentials
: 인증 정보 포함 허용 여부 (true
/false
)
예시
OPTIONS /api HTTP/1.1 Origin: https://정민.xyz Access-Control-Request-Method: POST Access-Control-Request-Headers: Content-Type
HTTP/1.1 200 OK Access-Control-Allow-Origin: https://정민.xyz Access-Control-Allow-Methods: GET, POST Access-Control-Allow-Headers: Content-Type
이후 실제 POST 요청이 정상적으로 진행된다.
Spring 기준 CORS 해결법
1. 컨트롤러 단위 설정 (@CrossOrigin
)
@RestController @RequestMapping("/api") @CrossOrigin(origins = "http://localhost:3000") // 허용할 프론트엔드 주소 public class MyController { @GetMapping("/data") public String getData() { return "Hello CORS"; } }
- 특정 컨트롤러 또는 메서드에만 적용 가능
origins
,methods
,allowedHeaders
등 옵션 설정 가능
2. 글로벌 설정 (Spring WebMvcConfigurer)
@Configuration public class WebConfig implements WebMvcConfigurer { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") // 모든 경로 허용 .allowedOrigins("http://localhost:3000") .allowedMethods("GET", "POST", "PUT", "DELETE") .allowedHeaders("*") .allowCredentials(true); } }
- 모든 요청에 대해 글로벌 CORS 설정 가능
- 프로젝트 규모가 크거나 여러 컨트롤러에서 공통으로 적용할 때 유용
마무리
CORS는 브라우저 보안을 위해 반드시 필요하지만, 외부 API 연동 시 자주 문제를 발생시키는 요소다.
Spring에서는 @CrossOrigin
또는 글로벌 설정을 통해 쉽게 문제를 해결할 수 있다.