CORS(Cross-Origin Resource Sharing) 에러는 프론트엔드와 백엔드가 다른 도메인/포트에서 실행될 때 자주 발생합니다.
http://localhost:3000 (Next.js)http://localhost:8080 (Spring Boot REST API)오류:
Access to fetch at 'http://localhost:8080/api/data' from origin 'http://localhost:3000' has been blocked by CORS policy
Spring Boot에서 CORS 문제를 해결하려면:
package com.example.demo.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.*;
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**") // 모든 API 경로 허용
.allowedOrigins("http://localhost:3000") // Next.js origin
.allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
.allowedHeaders("*")
.allowCredentials(true) // 인증 정보(쿠키 등) 허용
.maxAge(3600);
}
}
@RestController
@RequestMapping("/api")
@CrossOrigin(origins = "http://localhost:3000") // 이 컨트롤러에만 적용
public class ApiController {
@GetMapping("/data")
public ResponseEntity<String> getData() {
return ResponseEntity.ok("Hello from backend");
}
}
이 방법은 테스트/소규모 서비스에서는 간편하지만, 전역 적용이 필요할 땐 WebConfig를 추천합니다.
Spring Security를 사용 중이라면, CORS 허용을 명시적으로 추가해야 합니다.
안 그러면 필터 레벨에서 먼저 막히게 됩니다.
package com.example.demo.config;
import org.springframework.context.annotation.*;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.web.cors.*;
@Configuration
public class SecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.cors().configurationSource(corsConfigurationSource()) // CORS 허용 추가
.and()
.csrf().disable()
.authorizeHttpRequests()
.requestMatchers("/**").permitAll();
return http.build();
}
@Bean
public CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration config = new CorsConfiguration();
config.addAllowedOrigin("http://localhost:3000");
config.addAllowedMethod("*");
config.addAllowedHeader("*");
config.setAllowCredentials(true); // 쿠키/인증정보 전달 허용
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", config);
return source;
}
}
// pages/index.tsx
import { useEffect } from 'react';
export default function Home() {
useEffect(() => {
fetch('http://localhost:8080/api/data', {
credentials: 'include', // 쿠키 등 인증 정보 전달할 경우
})
.then(res => res.text())
.then(data => console.log(data));
}, []);
return <div>Next.js + Spring Boot CORS 테스트</div>;
}
credentials: 'include'를 설정한 경우, Spring 쪽에서도allowCredentials(true)반드시 필요
| 구성 | 설정 위치 | 설명 |
|---|---|---|
| Spring 전역 CORS | WebConfig.java | 전체 API에 CORS 허용 적용 |
| Spring Security | SecurityConfig.java | 필터단에서 CORS 허용 (Security 사용 시 필수) |
| Controller 단위 | @CrossOrigin | 개별 엔드포인트 CORS 허용 |
| Next.js | fetch(..., credentials) | 인증정보 보내는 경우 필요 |