[SpringBoot] CORS의 이해와 설정

2025. 1. 21. 21:07· Spring Framework/spring
목차
  1. CORS란?
  2. CORS 설정 방법
  3. 우리의 요청이 CORS를 적용하면 어떻게 동작하는가?
  4. CORS 설정은 하나라도 빠뜨리면 안 되나..??
반응형

 

보통 협업을 진행하다 보면 API 스펙을 전달해주고 완벽하게 테스트를 진행했는데도 들려오는 답변이 있습니다.

"API에서.. cors 에러가 발생해요.."

 

처음 협업을 진행하면서 CORS에 대해서 잘 모르기도 했었고, 스프링에서는 단순한 설정으로 이를 해결할 수 있었기 때문에 제대로 알아보고려고 하지 않았었죠.

 

이번에는 너무나 간단한 설정탓에 제대로 이해하지 못 했었던 CORS에 대해서 정리하고자 합니다.

 

CORS란?

 

CORS(Cross-Origin Resource Sharing)란, 클라이언트가 다른 출처(origin)에서 리소스를 요청할 때 발생하는 오류로 브라우저상에서 허용되지 않은 다른 출처를 제한하는 데 사용되는 보안 관련 오류입니다.

 

CORS는 보통 아래 두 가지 이유로 발생하게 됩니다.

  • 브라우저에서 출처(origin)가 다른 리소스에 접근할 때, 서버에서 명시적으로 해당 출처를 허용하지 않을 경우
  • 서버가 적절한 CORS 응답 헤더를 설정하지 않았거나, 설정이 클라이언트 요청과 일치하지 않을 경우

 

CORS 설정 방법

CORS의 개념은 다소 생소하고 이해하기 어려웠지만 설정 방법은 정말 간단한데요, 어디서 설정하는지에 다를뿐 결국 HTTP 응답 헤더에 설정한다는 목적은 같습니다.

 

보통 현업에서 사용할 때는 Security를 제외한 단일 모듈 안에서 MVC 설정 내부에 진행했었는데, 찾아보니 설정 방법이 정말 많았습니다.

 

아래는 스프링에서 CORS를 설정하는 여러가지 방법들입니다.

 

단일 컨트롤러에서의 설정

@RestController
@RequestMapping("/api")
public class ApiController {

    @CrossOrigin(origins = "http://example.com")
    @GetMapping("/data")
    public String getData() {
        return "Hello, CORS!";
    }
}

Spring MVC에서의 설정

@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**") // 모든 경로에 대해 적용
                .allowedOrigins("http://example.com") // 허용할 출처
                .allowedMethods("GET", "POST", "PUT", "DELETE") // 허용할 HTTP 메서드
                .allowedHeaders("*") // 허용할 헤더
                .allowCredentials(true); // 자격 증명 허용
    }
}

Spring Security에서의 설정

@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.cors().and()
            .csrf().disable() // CORS 설정과 함께 CSRF를 비활성화 (선택 사항)
            .authorizeRequests()
            .anyRequest().authenticated();
    }

    @Bean
    public CorsConfigurationSource corsConfigurationSource() {
        CorsConfiguration configuration = new CorsConfiguration();
        configuration.setAllowedOrigins(Arrays.asList("http://example.com")); // 허용할 출처
        configuration.setAllowedMethods(Arrays.asList("GET", "POST"));
        configuration.setAllowedHeaders(Arrays.asList("Authorization", "Content-Type"));
        configuration.setAllowCredentials(true);

        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", configuration);
        return source;
    }
}

직접 필터를 구현한 설정

@Component
public class CustomCorsFilter extends OncePerRequestFilter {

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
            throws ServletException, IOException {
        response.setHeader("Access-Control-Allow-Origin", "http://example.com");
        response.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
        response.setHeader("Access-Control-Allow-Headers", "Authorization, Content-Type");
        response.setHeader("Access-Control-Allow-Credentials", "true");

        if ("OPTIONS".equalsIgnoreCase(request.getMethod())) {
            response.setStatus(HttpServletResponse.SC_OK);
        } else {
            filterChain.doFilter(request, response);
        }
    }
}

 

 

우리의 요청이 CORS를 적용하면 어떻게 동작하는가?

 

위에서 CORS를 설정하기 위한 여러 방법들이 있었지만, 결국 목적은 HTTP 응답 값에 CORS 정책을 허용하는 값을 넣어준다는 같은 목적을 가지고 있습니다.

 

그러면, HTTP 응답 값에 CORS 정책을 허용하는 위 설정을 추가하면 어떻게 브라우저에서 동작하게 되는걸까요?

 

우선 클라이언트(Vue.js 등)의 요청이 브라우저로 들어오게 되면, 브라우저는 보안 정책에 따라 요청의 출처를 검사하고 서버의 출처가 다르기 때문에 다른 출처(Origin)에 대한 CORS 정책이 적용되게 됩니다.

 

이에 따라 서버에 Preflight 과정인 OPTIONS 요청을 보내어 서버에서는 이에 대한 CORS 설정을 응답으로 반환하고, 브라우저에서는 허용된 응답 값이 들어올 경우 추가적인 API 요청을 보내거나 들어오지 않을 경우 CORS 에러를 발생시키게 됩니다.

 

 

CORS 설정은 하나라도 빠뜨리면 안 되나..??

 

이게 참 궁금했고 각각의 설정이 빠짐에 따라 어떻게 동작하게 될지 궁금했습니다.

 

각 설정에 대한 특징과 빠드리게 될 경우 부수효과는 다음과 같습니다.

속성 기본값 누락 시 발생 상황
allowedOrigins 아무 출처도 허용하지 않음 Access-Control-Allow-Origin 헤더가 없으므로 모든 CORS 요청이 차단됨
allowedMethods GET, HEAD, POST만 허용 PUT, DELETE 등 허용되지 않은 메서드로 요청 시 CORS 오류 발생
allowedHeaders 기본 헤더(Content-Type, Cache-Control 등)만 허용 Authorization 또는 커스텀 헤더 요청 시 Preflight 요청 실패
allowCredentials false (자격 증명 허용 안 함) 클라이언트가 withCredentials: true를 설정하고 요청했을 때 CORS 오류 발생

 

상황에 따라 필요하지 않은 설정이 있을 수도 있으니 참고해서 개발하면 더 좋을 것 같습니다.

반응형
LIST

'Spring Framework > spring' 카테고리의 다른 글

[SpringBoot] Spring 버전 마이그레이션  (0) 2025.01.13
[SpringBoot] Spring Transaction에 대하여  (0) 2025.01.06
[SpringBoot] Spring FIiter  (0) 2024.12.29
[SpringBoot] ApplicationEvent를 활용한 이벤트 발행/구독  (0) 2024.12.28
[SpringBoot] @ComponentScan 동작 원리  (0) 2024.12.09
  1. CORS란?
  2. CORS 설정 방법
  3. 우리의 요청이 CORS를 적용하면 어떻게 동작하는가?
  4. CORS 설정은 하나라도 빠뜨리면 안 되나..??
'Spring Framework/spring' 카테고리의 다른 글
  • [SpringBoot] Spring 버전 마이그레이션
  • [SpringBoot] Spring Transaction에 대하여
  • [SpringBoot] Spring FIiter
  • [SpringBoot] ApplicationEvent를 활용한 이벤트 발행/구독
iron_jin
iron_jin
배운 것에 대한 내 생각을 가지고 정리하자
學而不思則罔(학이불사즉망)배운 것에 대한 내 생각을 가지고 정리하자
iron_jin
學而不思則罔(학이불사즉망)
iron_jin
전체
오늘
어제
  • 전체 (163)
    • 도서 (10)
    • 생각 정리 (0)
    • 후기 모음 (14)
    • 언어 (20)
      • css (1)
      • java (9)
      • Kotlin (0)
      • javascript (0)
      • Solidity (3)
      • Python (3)
      • GO (3)
      • C++ (1)
    • Spring Framework (32)
      • spring (16)
      • JPA (6)
      • Error (4)
      • Settings (4)
    • 알고리즘 (62)
      • 이론 (0)
      • 연습문제 (58)
    • 인프라 (6)
      • 클라우드 (1)
      • 도커 (0)
      • AWS (4)
      • Elastic Search (0)
    • 쿠버네티스 (3)
      • 이론 (0)
      • 실습 (2)
      • 트러블슈팅 (1)
    • Nginx (2)
    • CS (4)
      • 서버 (0)
      • 리눅스 (2)
      • 네트워크 (0)
      • OAuth (2)
    • 형상관리 (3)
      • GIT (3)
    • Open API (3)
      • 카카오 API (1)
      • QGIS (2)
    • 보안 (0)
      • 알고리즘 (0)
    • 공통 (1)
      • 성능 관리 도구 (1)
    • Database (2)
      • MySQL (1)
      • Redis (1)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • 2020 kakao
  • 2020 카카오 블라인드
  • Python
  • 항해99
  • MySQL
  • ddd
  • spring
  • 백준
  • 2019 kakao
  • Java
  • Hibernate
  • 2019 카카오
  • 2018 카카오 블라인드
  • 도메인 주도 개발
  • 알고리즘
  • 자바
  • 카카오 겨울 인턴십
  • 항해플러스
  • 2018 kakao
  • 2019 카카오 블라인드
  • 2020 카카오
  • SpringBoot
  • 프로그래머스
  • JPA
  • 에릭 에반스
  • 스프링
  • spring boot
  • 코딩테스트
  • 스프링 부트
  • AWS

최근 댓글

최근 글

hELLO · Designed By 정상우.v4.2.2
iron_jin
[SpringBoot] CORS의 이해와 설정
상단으로

티스토리툴바

개인정보

  • 티스토리 홈
  • 포럼
  • 로그인

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.