⚙️ 설정 방법⁉️ DELETE, PATCH 요청 오류 발생그 이유는…? 🤔그래서 어쩔..? 🐶🪬 설정 정보 분리 3가지 방법[공통] YAML 파일 설정1. 설정 정보를 클래스 파일로 분리2. @Value 사용3. @ConstructorBinding 사용 (By 진형님)🐶 Origin만 설정하고 모두 허용하기YAML 파일 설정
⚙️ 설정 방법
- 더미 컨트롤러 생성
@RestController @RequestMapping("/api/cors") public class CorsRestController { @GetMapping public ApiResponse<String> get() { return new ApiResponse<>("Accept Get Method!"); } @PostMapping public ApiResponse<String> post() { return new ApiResponse<>("Accept Post Method!"); } @PatchMapping public ApiResponse<String> patch() { return new ApiResponse<>("Accept Patch Method!"); } @DeleteMapping public ApiResponse<String> delete() { return new ApiResponse<>("Accept Delete Method!"); } }
- 더미 프론트 프로젝트 생성

해당 프로젝트는 에서 다운로드 후 손쉽게 사용 가능합니다.
(필요하신 분들은 README에서 소개된 내용대로 사용하면 됩니다. 😁 )
- 설정 파일 추가
@Configuration public class WebMvcConfig implements WebMvcConfigurer { public WebMvcConfig(CorsConfig corsConfig) { this.corsConfig = corsConfig; } @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/api/**") .allowedOrigins("http:localhost:3000"); } }
⁉️ DELETE
, PATCH
요청 오류 발생

로그 내역을 보면
GET
, POST
는 성공 했지만! DELETE
, PATCH
는 실패한 것을 확인할 수 있습니다.그 이유는…? 🤔
// ✨ 첫 번째 클래스 public class CorsRegistry { private final List<CorsRegistration> registrations = new ArrayList<>(); public CorsRegistration addMapping(String pathPattern) { // ✨ 여기서 설정 → 두 번째 클래스 CorsRegistration registration = new CorsRegistration(pathPattern); this.registrations.add(registration); return registration; } } // ✨ 두 번째 클래스 public class CorsRegistration { private final String pathPattern; private CorsConfiguration config; public CorsRegistration(String pathPattern) { this.pathPattern = pathPattern; // Same implicit default values as the @CrossOrigin annotation + allows simple methods // ✨ 여기서 Default 설정을 해주게 됩니다. → 마지막 클래스 this.config = new CorsConfiguration().applyPermitDefaultValues(); } } // ✨ 마지막 클래스 public class CorsConfiguration { // ✨ 여기서 Default Methods 값이 GET, POST 밖에 없는 것을 확인할 수 있습니다. private static final List<String> DEFAULT_PERMIT_METHODS = Collections.unmodifiableList( Arrays.asList(HttpMethod.GET.name(), HttpMethod.HEAD.name(), HttpMethod.POST.name())); public CorsConfiguration applyPermitDefaultValues() { if (this.allowedOrigins == null && this.allowedOriginPatterns == null) { this.allowedOrigins = DEFAULT_PERMIT_ALL; } if (this.allowedMethods == null) { this.allowedMethods = DEFAULT_PERMIT_METHODS; // ✨ 여기서 설정!! this.resolvedMethods = DEFAULT_PERMIT_METHODS .stream().map(HttpMethod::resolve).collect(Collectors.toList()); } if (this.allowedHeaders == null) { this.allowedHeaders = DEFAULT_PERMIT_ALL; } if (this.maxAge == null) { this.maxAge = 1800L; } return this; } }
그래서 어쩔..? 🐶
- allowedMethods를 통해 추가 설정 해주면 됩니다.
@Configuration public class WebMvcConfig implements WebMvcConfigurer { public WebMvcConfig(CorsConfig corsConfig) { this.corsConfig = corsConfig; } @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/api/**") .allowedOrigins("http:localhost:3000") .allowedMethods(HttpMethod.GET.name(), HttpMethod.POST.name(), HttpMethod.PATCH.name(), HttpMethod.DELETE.name()); } }
이렇게 해주고 나면…?

정상적으로 4개의 메서드가 모두 성공적으로 응답이 됩니다.
🪬 설정 정보 분리 3가지 방법
[공통] YAML 파일 설정
cors: allowed: api: /api/cors url: http://localhost:3000 method: GET, POST, PATCH, DELETE
1. 설정 정보를 클래스 파일로 분리
- CorsConfig 설정 파일 생성
@Configuration @ConfigurationProperties(prefix = "cors.allowed") public class CorsConfig { private String api; private String[] url; private String[] method; // Getter, Setter }
- 해당 설정 클래스를 이용해서 설정
여기서 두가지 어노테이션을 사용하고 있습니다.
1.
@AutoConfigureAfter
: CorsConfig 빈이 등록되고 난 후에 설정되도록 사용 2.@ConditionalOnBean
: 해당 빈이 존재하면 설정 되도록 추가
@AutoConfigureAfter(CorsConfig.class) @ConditionalOnBean(CorsConfig.class) @Configuration public class WebMvcConfig implements WebMvcConfigurer { private final CorsConfig corsConfig; public WebMvcConfig(CorsConfig corsConfig) { this.corsConfig = corsConfig; } @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping(api) .allowedOrigins(corsConfig.getUrl()) .allowedMethods(corsConfig.getMethod()); } }
2. @Value
사용
@Configuration public class WebMvcConfig implements WebMvcConfigurer { private final CorsConfig corsConfig; @Value("${cors.allowed.api}") private String api; @Value("${cors.allowed.url}") private String[] url; @Value("${cors.allowed.method}") private String[] method; public WebMvcConfig(CorsConfig corsConfig) { this.corsConfig = corsConfig; } @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping(api) .allowedOrigins(url) .allowedMethods(method); } }
3. @ConstructorBinding
사용 (By 진형님)
- 설정 파일 생성
@ConstructorBinding // ✨ Setter 메서드를 사용하지 않고 생성자를 통해서 주입!! @ConfigurationProperties(prefix = "cors.v2.allowed") public record CorsConfigV2 ( String api, String[] url, String[] method ) { }
- ConfigurationPropertiesScan 을 사용해서 빈 등록 후 해당 클래스로 설정
@ConfigurationPropertiesScan("com.kdt.instakyuram.config") @Configuration public class WebMvcConfigV4 implements WebMvcConfigurer { CorsConfigV2 corsConfig; public WebMvcConfigV4(CorsConfigV2 corsConfig) { this.corsConfig = corsConfig; } @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping(corsConfig.api()) .allowedOrigins(corsConfig.url()) .allowedMethods(corsConfig.method()); } }
🐶 Origin만 설정하고 모두 허용하기
YAML 파일 설정
cors: allowed: api: /** origins: - http://localhost:3000 - http://127.0.0.1:3000 methods: *
나머지는 위의 [설정 정보 분리 3가지 방법]과 동일