Backend/Spring(활용)

CORS 오류를 해결하기 위한 다양한 방법

개발자-제이 2025. 2. 26. 17:50

 

1. CORS란 무엇인가?

CORS(Cross-Origin Resource Sharing)는 브라우저에서 보안상의 이유로 서로 다른 출처(Origin) 간의 HTTP 요청을 제한하는 정책이다.
즉, http://localhost:3000(프론트엔드 개발 서버)에서 실행되는 JavaScript가 http://localhost:8080(백엔드 서버)로 API 요청을 보낼 때, 기본적으로 브라우저는 이를 차단한다.

CORS 오류 예시

Access to XMLHttpRequest at 'http://localhost:8080' 
from origin 'http://localhost:3000' has been blocked by CORS policy

CORS가 필요한 이유

 

  • 보안 강화를 위해 기본적으로 브라우저는 다른 출처의 요청을 차단
  • API 서버에서 특정 도메인만 허용하도록 설정 가능
  • 클라이언트(프론트)에서 요청을 보낼 때 적절한 헤더 및 인증 정보 설정 필요

 

2. Spring Boot 전역 CORS 설정

 

Spring Boot에서 CORS를 허용하는 가장 일반적인 방법은 전역적으로 CORS 설정을 추가하는 것이다.

Spring Boot 글로벌 CORS 설정 (WebMvcConfigurer 사용)

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class CorsConfig {
    @Bean
    public WebMvcConfigurer corsConfigurer() {
        return new WebMvcConfigurer() {
            @Override
            public void addCorsMappings(CorsRegistry registry) {
                registry.addMapping("/**")
                        .allowedOrigins("http://localhost:3000") // 프론트 개발 서버 주소
                        .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
                        .allowedHeaders("*")
                        .allowCredentials(true);
            }
        };
    }
}

설정 설명

  • allowedOrigins("http://localhost:3000") → 프론트 개발 서버에서의 요청을 허용
  • allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS") → 허용할 HTTP 메서드 지정
  • allowCredentials(true) → 인증 정보(쿠키 등)를 포함한 요청 허용

 

3. 컨트롤러 단에서 CORS 설정

Spring Boot 전역 설정 외에도, 특정 컨트롤러에서만 CORS를 적용할 수도 있다.

@CrossOrigin 사용

import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/rest/v1")
@CrossOrigin(origins = "http://localhost:3000")  // 프론트 개발 서버 주소
public class FileController {
    
    @PostMapping("/upload")
    public ResponseEntity<String> uploadFile() {
        return ResponseEntity.ok("File uploaded successfully!");
    }
}

✔ @CrossOrigin(origins = "http://localhost:3000")을 사용하면 특정 컨트롤러에서만 CORS 허용 가능
✔ 전체 API에 대한 CORS 허용이 불필요할 경우 유용

 

4. Spring Security 사용 시 CORS 설정

Spring Security를 사용하는 경우, CORS 설정을 별도로 추가해야 한다.

Spring Security CORS 설정

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.web.SecurityFilterChain;

@Configuration
@EnableWebSecurity
public class SecurityConfig {

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {

        http
                .cors((corsCustomizer -> corsCustomizer.configurationSource(new CorsConfigurationSource() {

                    @Override
                    public CorsConfiguration getCorsConfiguration(HttpServletRequest request) {

                        CorsConfiguration configuration = new CorsConfiguration();

                        configuration.setAllowedOrigins(Collections.singletonList("http://localhost:3000"));
                        configuration.setAllowedMethods(Collections.singletonList("*"));
                        configuration.setAllowCredentials(true);
                        configuration.setAllowedHeaders(Collections.singletonList("*"));
                        configuration.setMaxAge(3600L);

                        configuration.setExposedHeaders(Collections.singletonList("Authorization"));

                        return configuration;
                    }
                })));

 
        return http.build();
    }
}

- Spring Security가 활성화된 경우 반드시 http.cors()를 추가해야 CORS 설정이 정상 동작

 

5.Axios 요청에서 CORS 설정

Spring Boot에서 allowCredentials(true)를 설정했다면, 프론트에서 Axios 요청을 보낼 때 withCredentials: true를 추가해야 한다.

Axios 요청 시 CORS 허용 설정

import axios from 'axios';

axios.post('http://localhost:8080/rest/v1/upload', formData, {
  headers: {
    'Content-Type': 'multipart/form-data'
  },
  withCredentials: true
})
.then(response => {
  console.log(response.data);
})
.catch(error => {
  console.error(error);
});
  •  withCredentials: true가 없으면 쿠키 및 세션 정보가 포함되지 않음
  • Content-Type을 적절히 지정하여 API 서버와 일치하도록 설정

 

6. 브라우저 캐시 삭제 및 추가 점검

브라우저 캐시 삭제 방법

  1. F12(개발자 도구) → 애플리케이션 → 저장소 삭제
  2. Shift + Ctrl + R (강제 새로고침)
  3. 쿠키 및 로컬 스토리지 삭제 후 다시 테스트

 

7. 정리

  • Spring Boot에서 전역 CORS 설정 (WebMvcConfigurer 활용)
  • 특정 컨트롤러에서만 CORS 적용 (@CrossOrigin)
  • Spring Security가 활성화된 경우 별도 CORS 설정 필요
  • 프론트에서 Axios 요청 시 withCredentials: true 설정 필요
  • 브라우저 캐시를 삭제한 후 다시 테스트
반응형