JAVA

Java에서의 CORS 설정하기

ghyeong 2024. 10. 18. 04:13
반응형

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를 적절하게 설정함으로써, 다양한 클라이언트 애플리케이션과의 상호작용을 원활하게 할 수 있습니다.

반응형