일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- 1차원 DP
- 2차원 dp
- 99클럽
- @GeneratedValue
- @GenericGenerator
- @Transactional
- Actions
- Amazon EFS
- amazon fsx
- Android Studio
- ANSI SQL
- async/await
- AVG
- AWS
- Azure
- bind
- builder
- button
- c++
- c++ builder
- c03
- Callback
- case when
- CCW
- chat GPT
- CICD
- Collections
- Combination
- combinations
- Comparator
- Today
- Total
기록
CORS 오류 해결하기: Spring Boot와 Swagger 본문
시작하면서
웹 개발을 하다 보면 자주 겪게 되는 오류 중 하나가 CORS (Cross-Origin Resource Sharing) 관련 오류입니다. 이는 브라우저에서 다른 출처의 리소스를 요청할 때 발생하는 보안 문제로, 주로 API 서버와 클라이언트가 서로 다른 도메인에 있을 때 나타납니다. 오늘은 Spring Boot와 Swagger를 사용한 프로젝트에서 발생한 CORS 오류를 해결한 경험을 공유하며, CORS의 개념과 문제 해결 방법을 다뤄보겠습니다.
CORS란 무엇인가?
CORS는 Cross-Origin Resource Sharing의 약자로, "교차 출처 리소스 공유"를 의미합니다. 쉽게 말해, 한 웹 애플리케이션에서 실행되는 JavaScript 코드가 다른 도메인에 존재하는 리소스를 요청할 때 발생하는 보안 규칙입니다. 기본적으로, 웹 브라우저는 보안상의 이유로 다른 출처(origin)의 리소스를 요청하는 것을 차단합니다. 예를 들어, http://example.com
에서 실행되는 웹 페이지가 http://api.example.com
에서 제공하는 API를 호출하려고 하면, 브라우저는 이 요청을 차단할 수 있습니다.
이때, 서버에서 CORS 헤더를 통해 특정 도메인에 대해 요청을 허용하면, 브라우저가 해당 요청을 차단하지 않고 허용하게 됩니다.
CORS 오류의 원인
CORS 오류는 주로 클라이언트(브라우저)에서 API를 호출할 때 서버가 요청을 허용하지 않아서 발생합니다. 예를 들어, Spring Boot 서버가 localhost:8080
에서 실행되고 있고, 클라이언트가 localhost:3000
에서 실행되는 React 애플리케이션이라면, 서버는 기본적으로 다른 출처의 요청을 차단하게 됩니다. 이때 CORS 오류가 발생합니다.
CORS 오류 해결 과정
처음에는 다음과 같은 코드로 서버 URL을 동적으로 설정했습니다:
fun openApi(): OpenAPI {
val profile: String = environment.getProperty("spring.profiles.active", "local")
val host: String = InetAddress.getLocalHost().hostAddress
val port: String = environment.getProperty("ec2.$profile.port", "8080")
val version: String = environment.getProperty("apiProject.version", "V.0.0.0")
val server = Server()
server.url = "http://$host:$port"
return OpenAPI().servers(listOf(server))
.info(
Info()
.title("[$profile] Ilsang Api Document")
.description("$profile 환경에서의 API 문서입니다.")
.version("$version")
)
.security(
listOf(
SecurityRequirement()
.addList("authorization")
)
)
}
문제가 발생한 환경
Spring Boot와 Kotlin을 사용하여 API 서버를 개발하는 프로젝트에서 Swagger를 사용하고 있었습니다. Swagger는 API 문서화와 테스트를 돕는 도구로, 개발 중 자주 사용됩니다. 그러나 Swagger UI를 통해 API를 테스트하려고 할 때 CORS 오류가 발생했습니다. 문제의 원인은 EC2 환경에서 Swagger UI가 사용하는 서버 주소 설정이 실제 사용자들이 접근하는 주소와 일치하지 않았기 때문입니다.
문제 상황의 세부 원인 파악
이 프로젝트에서는 EC2 인스턴스에 Elastic IP (EIP)를 할당하여 사용자가 고정된 퍼블릭 IP를 통해 서버에 접근할 수 있도록 구성했습니다. 그러나 Spring Boot 설정에서 Swagger의 서버 주소를 가져오기 위해 InetAddress.getLocalHost().hostAddress
를 사용했는데, 이 코드가 EC2의 Private IP를 반환했습니다. 그 결과, Swagger가 요청을 보낼 때 API 서버의 주소가 Private IP로 설정되었고, 사용자가 접속하는 EIP와는 서로 다른 출처(Cross-Origin)로 인식되어 CORS 오류가 발생했습니다.
문제 해결을 위한 수정
- 환경별 호스트 IP 정보 명시
ec2:
prd:
host: ${ELP_PRD}
port: 8881
dev:
host: ${ELP_DEV}
port: 8880
local:
host: localhost
port: 8080
- .yml을 읽어와서 주소 정보를 설정하도록 수정
CORS 오류를 해결하기 위해, 서버의 주소 설정 방식을 변경했습니다. InetAddress.getLocalHost().hostAddress
를 사용하던 부분을, 프로파일에 맞춰 서버 주소를 설정하는 방식으로 수정했습니다.
수정된 코드:
fun openApi(): OpenAPI {
val profile: String = environment.getProperty("spring.profiles.active", "local")
val host: String = environment.getProperty("ec2.$profile.host", "localhost")
val port: String = environment.getProperty("ec2.$profile.port", "8080")
val version: String = environment.getProperty("apiProject.version", "V.0.0.0")
val server = Server()
server.url = "http://$host:$port"
return OpenAPI().servers(listOf(server))
.info(
Info()
.title("[$profile] Ilsang Api Document")
.description("$profile 환경에서의 API 문서입니다.")
.version("$version")
)
.security(
listOf(
SecurityRequirement()
.addList("authorization")
)
)
}
이렇게 함으로써 Swagger UI가 고정된 서버 URL을 사용하게 되어 CORS 문제가 해결되었습니다.
(다른방법) CORS 오류 해결 방법
CORS 오류를 해결하기 위한 몇 가지 방법은 다음과 같습니다:
- 서버에서 CORS 정책 설정:
Spring Boot에서는@CrossOrigin
어노테이션을 사용하거나CorsRegistry
를 통해 CORS 정책을 설정할 수 있습니다. 이를 통해 특정 도메인만 허용하거나 모든 도메인에서의 요청을 허용할 수 있습니다.@Configuration class WebConfig : WebMvcConfigurer { override fun addCorsMappings(registry: CorsRegistry) { registry.addMapping("/**") .allowedOrigins("http://localhost:3000") // 허용할 클라이언트 주소 .allowedMethods("GET", "POST", "PUT", "DELETE") } }
- 예시 코드:
- 서버 URL을 환경에 맞게 동적으로 설정:
위에서 설명한 것처럼, 서버의 호스트와 포트 정보를 환경 설정에 맞춰 동적으로 지정하면 CORS 오류를 피할 수 있습니다. 개발 환경, 테스트 환경, 프로덕션 환경에 따라 서버 주소가 달라지므로, 이를 동적으로 설정하는 방식이 필요합니다. - 프록시 서버 사용:
개발 중이라면 프록시 서버를 사용하여 CORS 문제를 우회할 수 있습니다. 예를 들어,create-react-app
에서는proxy
설정을 통해 CORS 문제를 해결할 수 있습니다.
마무리하면서
CORS 오류는 클라이언트와 서버가 서로 다른 출처에서 리소스를 요청할 때 발생하는 보안 관련 문제입니다. Spring Boot와 Swagger를 사용하면서 경험한 CORS 오류를 해결하는 과정에서, CORS가 발생하는 원인과 이를 해결하는 방법에 대해 더 깊이 이해할 수 있었습니다.
'Web > Spring' 카테고리의 다른 글
[자바 ORM 표준 JPA 프로그래밍] JPA 시작하기: 개발 환경부터 객체 매핑까지(2장) (0) | 2024.11.14 |
---|---|
[Spring] URI 기반 권한제어 : Spring Boot 필터 및 Swagger 설정 (0) | 2024.11.04 |
MyBatis/ bind 태그 사용법 (0) | 2024.08.19 |
경험치 시스템 구현(2): 인터페이스를 사용한 동적 경험치 부여 (0) | 2024.06.17 |
경험치 시스템 구현(1): 어드바이스와 커스텀 어노테이션 활용 (0) | 2024.06.10 |