이해하기 쉬운 CORS 및 API 개발 안내서 (Access-Control-Allow-Headers)
웹 개발을 하다 보면 'CORS'라는 용어를 자주 접하게 된다. CORS 관련 에러도 자주 마주치다 보니 한번 제대로 이해해 보는 시간을 가져보자!
CORS는 Cross-Origin Resource Sharing의 약자로, 한 출처에서 불러온 웹 페이지가 다른 출처의 리소스와 상호 작용할 수 있게 하는 보안 메커니즘이다. 이 글에서는 CORS가 왜 중요한지, 어떻게 작동하는지, 그리고 실제 API 개발에 어떻게 적용되는지를 알아보자!
1. 출처(Origin)란 무엇인가?
웹에서 "출처"는 리소스가 어디에서 왔는지를 식별하는 중요한 개념이다. 출처는 URL의 세 가지 주요 구성 요소인 프로토콜(예: http 또는 https), 호스트(도메인 이름), 그리고 포트 번호로 정의된다. 이 세 가지가 모두 일치할 때 두 URL은 "동일 출처"로 간주된다.
예를 들어, https://www.example.com에서 프로토콜은 https, 호스트는 www.example.com이다. 만약 포트 번호가 URL에 명시되지 않았다면, 프로토콜의 기본 포트인 https(443) 또는 http(80)이 암묵적으로 사용된다.
2. CORS는 어떻게 작동하는가?
CORS는 웹 페이지가 다른 출처의 리소스를 안전하게 요청할 수 있게 하는 메커니즘이다.
기본적으로 브라우저는 동일 출처 정책(Same-Origin Policy)을 적용하여 다른 출처의 리소스와의 상호작용을 제한한다. 그러나 서버는 특정 HTTP 헤더를 통해 이 정책에 예외를 부여할 수 있다.
- 요청의 CORS 처리 과정:
- 브라우저의 요청
- 예를 들어, https://myapp.com 페이지에서 https://api.example.com/data로 데이터를 요청한다.
- 브라우저는 이 요청에 자동으로 'Origin: https://myapp.com' 헤더를 추가해서 서버에 보낸다.
- 서버의 응답
- api.example.com 서버는 요청을 받고 처리한다.
- 만약 myapp.com이 데이터에 접근할 수 있게 하고 싶다면, 서버는 응답 헤더에 Access-Control-Allow-Origin: https://myapp.com 을 추가한다.
- 모든 출처에 대해 허용하고 싶다면, Access-Control-Allow-Origin: *라고 설정할 수도 있다.
- 브라우저의 검증
- 브라우저는 서버로부터 받은 응답의 CORS 헤더를 확인한다.
- 응답 헤더에 Access-Control-Allow-Origin이 요청 헤더의 Origin과 일치하거나 *인 경우, 브라우저는 요청을 허용한다.
- 응답의 실행 또는 차단
- 만약 응답이 CORS 정책을 만족하면, 브라우저는 응답에 포함된 데이터를 웹 페이지에 전달하여 사용할 수 있게한다.
- 만약 만족하지 않는다면, 브라우저는 응답을 차단하고, 웹 페이지는 데이터에 접근할 수 없게 된다.
3. CORS 설정하기
CORS 설정은 서버에서 이루어진다. Spring Boot를 사용하는 경우 다음과 같은 방법으로 CORS를 설정할 수 있다:
- 아래 설정은 https://www.example.com 출처에서 오는 요청에 대해 GET, POST, PUT, DELETE, OPTIONS 메소드를 허용한다.
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("https://www.example.com")
.allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS");
}
}
4. 세부적인 CORS의 영향과 리소스 낭비 문제
요청 헤더의 Origin
서버가 응답을 반환할 때, 요청에서 받은 Origin 헤더는 기본적으로 응답에 포함되지 않는다. 즉, 요청으로 받은 header는 응답에서 초기화된다는 뜻이다. 서버는 Access-Control-Allow-Origin 헤더를 명시적으로 설정해야만 브라우저가 리소스에 접근할 수 있게 한다.
리소스 낭비의 문제
CORS 정책 위반 시, 브라우저는 서버로부터 받은 응답을 웹 페이지로 전달하지 않는다. 즉, 서버는 요청을 처리하고 응답을 반환하지만, CORS 정책을 만족하지 않는 경우 브라우저는 이 응답을 차단하고 웹 페이지는 데이터에 접근할 수 없게 된다.
이 과정은 네트워크 트래픽과 서버 자원의 사용을 수반하지만, 브라우저가 응답을 차단함으로써 최종 사용자에게는 아무런 이득이 없게 된다. 이런 의미에서, 서버와 클라이언트 사이에 발생하는 CORS 오류는 리소스 낭비라고 볼 수 있다. 특히, 대규모 웹 애플리케이션에서 이러한 요청과 응답이 많아질수록, 불필요한 데이터 전송으로 인한 리소스 낭비가 누적되어 전체 시스템의 효율성에 영향을 줄 수 있다.
따라서, 서버에서는 올바른 CORS 정책을 설정하고, 프론트엔드 개발자는 불필요한 요청이 서버에 도달하지 않도록 주의 깊게 코드를 작성하여 이러한 문제를 최소화해야 한다.
결론
CORS는 웹 애플리케이션의 보안을 강화하는 중요한 기능이며, 서버와 클라이언트 모두에서 올바르게 구성되어야 한다.
이를 통해 웹 애플리케이션은 다양한 출처의 리소스를 안전하게 활용할 수 있다.
5. 마무리
웹 개발과 API 개발을 진행하면서 CORS 관련 오류를 여러 번 마주쳤었다. 이전에는 단순히 문제를 해결하는 데 급급해 구성 코드에 프론트엔드 서버 주소만 추가하는 식으로 대응했었다.
그러나 이번에 CORS에 대해 깊이 있게 공부하고 정리하면서, 그동안 사용했던 코드가 담고 있는 의미를 이해하게 되었다. 이 경험을 통해 앞으로는 CORS 오류를 예방하고 더 나은 웹 애플리케이션을 구축하는 데 주의를 기울일 것이다.
이 글이 CORS에 대한 명확한 이해와 함께, 같은 오류를 마주하는 다른 개발자들에게도 도움이 되기를 바란다.
[AWS] ECS, ALB - 동적 포트 매핑 활성화와 DNS 접속
'Spring > Spring Boot' 카테고리의 다른 글
[Spring Boot] Spring Batch 코드 작성 후 실행 시 Table doesn't exist 에러 해결 (0) | 2023.11.07 |
---|---|
[Spring Boot] 의존성 버전문제로 인한 오류 해결 (1) | 2023.11.07 |
[Spring Boot] RequestDTO로 요청받을때 @RequestBody를 작성하는 경우와 작성하지 않는 경우 (1) | 2023.11.07 |
[Spring Boot] Custom Annotation 만들기 - AOP(Aspect-Oriented Programming) (1) | 2023.10.24 |
[Spring Boot] Custom Annotation 만들기 - 메타 어노테이션 (2) | 2023.10.23 |