FE팀에서 개발 중 Swagger UI에서 API 테스트를 위해 Execute
버튼을 눌렀는데 CORS 오류가 발생했다. 처음엔 Spring Security 설정에 문제가 있는 줄 알고 CORS origin을 추가했지만, 문제가 해결되지 않았다. 원인을 찾아보다가 Swagger 자체 설정도 고려해야 한다는 것을 알게 되었고, 결국 SwaggerConfig와 SecurityConfig를 함께 설정하면서 문제를 해결할 수 있었다.
CORS(Cross-Origin Resource Sharing)는 브라우저의 보안 정책 중 하나로, 다른 origin으로 요청을 보낼 때 이를 제어한다. 여기서 origin은 프로토콜 + 도메인 + 포트
조합을 의미한다.
예를 들어, 클라이언트가 http://localhost:3000
에서 실행 중인데 API 서버는 http://localhost:8080
이라면, 서로 다른 origin으로 판단되어 브라우저가 보안 상 요청을 차단한다. 이때 서버가 명시적으로 해당 origin을 허용해야만 정상적인 요청이 가능하다.
Swagger UI가 백엔드 서버와 동일한 origin에서 실행될 경우, 예를 들어 http://localhost:8080/swagger-ui/index.html
처럼 Swagger 문서가 백엔드 서버에서 함께 서빙되고 있을 때는 CORS 오류가 발생하지 않는다. 이 경우에는 브라우저 입장에서 동일한 origin으로의 요청이기 때문에 setAllowedOrigins()
설정 없이도 API 요청이 가능하다.
반대로, 프론트엔드 개발 중 Swagger UI를 http://localhost:3000
같은 다른 origin에서 띄우는 경우, Swagger가 백엔드 서버(localhost:8080
)로 요청을 보내면서 브라우저가 CORS 정책 위반으로 차단한다.
이런 경우에는 Spring Security에서 아래와 같이 CORS 설정을 해줘야 한다.
configuration.setAllowedOrigins(List.of("http://localhost:3000"));
CORS 설정만으로 문제가 해결되지 않는 경우가 있다. Swagger UI는 OpenAPI 문서에 명시된 서버 주소를 기준으로 API 요청을 보내는데, 별도로 서버 주소를 설정하지 않으면 Swagger가 문서를 호스팅하고 있는 origin이 아닌 다른 경로로 요청을 보낼 수도 있다.
이럴 때는 SwaggerConfig에 아래와 같이 서버 주소를 명시적으로 설정해줘야 한다.
@Bean
public OpenAPI openAPI() {
return new OpenAPI()
.addServersItem(new Server().url("/"));
}
이 설정은 Swagger가 현재 문서를 띄우고 있는 origin을 기준으로 상대경로로 API 요청을 보내도록 한다.
Swagger를 사용할 때 CORS 문제 없이 API 요청이 잘 되기 위해서는 아래 두 가지 설정이 모두 필요할 수 있다.
설정 | 목적 | 이유 |
---|---|---|
SwaggerConfig.addServersItem(...) | Swagger UI가 올바른 주소로 요청하도록 설정 | 잘못된 경로로의 요청 방지 |
SecurityConfig.setAllowedOrigins(...) | 해당 origin에서 오는 요청을 허용 | 브라우저의 CORS 오류 방지 |
배포 환경에서는 실제 도메인(https://example.com
)도 CORS 허용 목록에 포함해줘야 한다. 프론트엔드 개발 환경(localhost:3000)에서도 Swagger를 통해 API 테스트를 원활하게 하려면 위의 설정을 모두 확인해봐야한다.