Java에서의 CORS 설정하기
CORS란 무엇인가?
CORS(Cross-Origin Resource Sharing)는 웹 브라우저가 한 출처의 웹 애플리케이션이 다른 출처의 리소스에 접근할 수 있도록 허용하는 메커니즘입니다. 기본적으로 웹 브라우저는 보안을 위해 동일 출처 정책(Same-Origin Policy)을 따릅니다. 이 정책에 따르면, 다른 출처의 리소스에 대한 접근이 제한됩니다. CORS는 이러한 제한을 완화하여, 서버에서 특정 출처의 요청을 허용할 수 있도록 합니다.
CORS는 마치 우리 부모님처럼, 다른 집에 들어가는 걸 엄격히 지키지만, 간혹 마음에 드는 친구가 오면 문을 열어주곤 하죠.
동일 출처 정책(Same-Origin Policy)
동일 출처 정책은 웹 보안의 기본 원칙으로, 스크립트가 다른 출처에서 실행되는 문서의 데이터에 접근하는 것을 제한합니다. 출처는 프로토콜(예: HTTP, HTTPS), 도메인(예: example.com), 포트(예: 80, 443)로 구성됩니다. 동일 출처 정책에 의해 JavaScript 코드가 다른 출처의 데이터를 직접 요청할 수 없게 됩니다.
CORS의 작동 원리
CORS는 클라이언트가 요청을 보내기 전에 브라우저가 서버에 OPTIONS 요청을 보내는 프리플라이트(preflight) 요청을 사용하여 작동합니다. 이 요청을 통해 서버가 해당 출처에서의 요청을 허용하는지 확인합니다. 서버는 다음과 같은 CORS 관련 헤더를 포함하여 응답합니다:
- Access-Control-Allow-Origin: 허용할 출처
- Access-Control-Allow-Methods: 허용할 HTTP 메서드 (GET, POST 등)
- Access-Control-Allow-Headers: 허용할 헤더
예시: 프리플라이트 요청
프리플라이트 요청은 마치 친구에게 파티에 초대하기 전에 "이런 저런 사람들 오는데 괜찮나요?"라고 확인하는 것과 같습니다. 친구가 괜찮다고 대답하면, 그제야 초대장을 보내는 것이죠.
Java에서 CORS 설정하기
Java 웹 애플리케이션에서 CORS를 설정하는 방법은 여러 가지가 있으며, 주로 Spring Framework를 사용하는 경우 다음과 같은 방법들을 활용할 수 있습니다.
글로벌 CORS 설정
가장 일반적인 방법으로, WebMvcConfigurer를 구현하여 애플리케이션 전체에 CORS 설정을 적용하는 것입니다. WebConfig 클래스를 만들어 설정할 수 있습니다.
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("http://localhost:3000")
.allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
.allowedHeaders("*")
.allowCredentials(true)
.maxAge(3600);
}
}
개별 컨트롤러에 CORS 설정하기
CORS 설정을 개별 컨트롤러에 적용할 수도 있습니다. 이 경우, @CrossOrigin 어노테이션을 사용하여 해당 컨트롤러나 메서드에 CORS 설정을 추가할 수 있습니다.
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@CrossOrigin(origins = "http://localhost:3000") // 특정 출처에 대해 CORS 허용
public class MyController {
@GetMapping("/api/resource")
public String getResource() {
return "Hello, CORS!";
}
}
예시: @CrossOrigin 어노테이션
@CrossOrigin 어노테이션을 사용하는 것은 마치 "특정 친구는 초대할게" 라고 정하는 것과 같습니다. 이 친구가 아닌 사람은 초대하지 않겠다는 뜻이죠.
CORS 설정을 위한 필터 사용하기
CORS 설정을 필터로 구현할 수도 있습니다. 이를 통해 CORS 관련 헤더를 수동으로 추가할 수 있습니다. Filter 인터페이스를 구현하여 사용할 수 있습니다.
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class SimpleCORSFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletResponse httpResponse = (HttpServletResponse) response;
httpResponse.setHeader("Access-Control-Allow-Origin", "http://localhost:3000");
httpResponse.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
httpResponse.setHeader("Access-Control-Allow-Headers", "*");
chain.doFilter(request, response);
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {}
@Override
public void destroy() {}
}
예시: @CORS 어노테이션
@CORS 필터는 특정 출처를 확인하고 필요한 헤더를 추가하는 역할을 하며, 이는 마치 “VIP 손님을 위한 특별 경호원”과 같습니다. 허용된 출처만 드나들 수 있도록 관리하죠.
Spring Security와 CORS 설정
Spring Security를 사용하는 경우, CORS 설정을 보안 구성에 추가해야 합니다. Spring Security 설정 클래스에서 CORS를 구성할 수 있습니다.
import org.springframework.context.annotation.Bean;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.cors() // CORS 설정을 추가
.and()
.authorizeRequests()
.anyRequest().authenticated();
}
@Bean
public CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(Arrays.asList("http://localhost:3000"));
configuration.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "DELETE", "OPTIONS"));
configuration.setAllowCredentials(true);
configuration.setAllowedHeaders(Arrays.asList("*"));
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
}
CORS 오류 해결하기
CORS 설정이 올바르게 되어 있음에도 불구하고 요청이 차단되는 경우가 있습니다. 이 경우 브라우저의 개발자 도구를 사용하여 네트워크 요청을 확인하고, 어떤 CORS 관련 오류 메시지가 발생했는지 확인합니다. 일반적인 CORS 오류와 그 해결 방법은 다음과 같습니다:
- Access-Control-Allow-Origin 오류: 요청한 출처가 서버의 CORS 정책에 등록되어 있지 않을 때 발생합니다. allowedOrigins에 정확한 출처를 추가해야 합니다.
- HTTP 메서드 오류: 요청에서 사용한 HTTP 메서드가 허용되지 않았을 경우 발생합니다. allowedMethods에 필요한 메서드를 추가해야 합니다.
- Credentials 오류: 인증 정보를 포함한 요청에서 CORS 설정이 맞지 않을 때 발생합니다. allowCredentials(true)로 설정해야 하며, allowedOrigins에는 와일드카드(*) 대신 정확한 출처를 지정해야 합니다.
결론
CORS 설정은 Java 웹 애플리케이션에서 다른 출처의 리소스에 접근할 수 있도록 허용하는 중요한 과정입니다. Spring Boot에서는 여러 가지 방법으로 CORS를 설정할 수 있으며, 필요에 따라 글로벌 설정, 컨트롤러별 설정, 필터 사용, Spring Security와의 통합 등 다양한 방법을 선택할 수 있습니다. 보안에 유의하면서 필요한 출처만을 허용하는 것이 중요합니다. CORS를 적절하게 설정함으로써, 다양한 클라이언트 애플리케이션과의 상호작용을 원활하게 할 수 있습니다.