SpringBoot(백엔드), React(프론트엔드) 사이 CORS 문제
SpringBoot(백엔드), React(프론트엔드) 사이 CORS 문제
SpringBoot(백엔드), React(프론트엔드) 사이 CORS 문제
서버는 스프링부트이고, 프론트 단은 React를 사용하였는데 서버에 Request를 요청할 때 CORS 에러가 발생했다.
CORS는 무엇일까?
교차 출처 리소스 공유를 뜻하는 CORS는 서로 다른 출처에서 리소스를 공유하는 것을 뜻한다.
여기서 출처
란 다음의 사진을 보자.
URL은 https://www.domain.com:3000/user?query=name&page=1와 같은 형태로 이루어져 있다.
여기서 Protocol
, Host
, Port
를 합쳐서 부르는 말이 Origin(출처)
이다.
CORS 허용 설정을 하지 않으면 서버와 다른 Origin을 가진 곳에서 서버의 Origin에 요청을 보내면 CORS 에러가 발생한다.
프로젝트를 하며 CORS 에러가 발생했다.
1
Access to fetch at 'http://localhost:8080/api/users/login' from origin 'http://localhost:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
1
2
3
4
5
6
7
8
9
10
11
12
13
@Configuration
public class WebSecurityConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry
.addMapping("/**")
.allowedOrigins("http://localhost:3000")
.allowedMethods("GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS")
}
}
보통은 다음과 같이 addCorsMappings 메서드를 오버라이딩하여 모든 RequestMapping에 대하여 통신을 주고 받는 React Origin의 요청에 대해 CORS를 허용하면 됐었다.
하지만 이런 방법으로는 해결되지 않았다..😂
SecurityConfig
파일에서 다음을 추가해 주면 된다.
1
2
3
4
5
6
7
8
9
10
11
12
13
@Bean
public CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
configuration.addAllowedOrigin("http://localhost:3000"); // 허용할 프론트엔드 도메인
configuration.addAllowedMethod("*"); // 모든 HTTP 메서드 허용
configuration.addAllowedHeader("*"); // 모든 헤더 허용
configuration.setAllowCredentials(true); // 인증 정보를 포함한 요청 허용
configuration.addExposedHeader("Authorization");
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration); // 모든 경로에 대해 설정 적용
return source;
}
addAllowedOrigin("http://localhost:3000")
:localhost:3000
에서 온 요청만 허용.addAllowedMethod("*")
: 모든 HTTP 메서드 (GET, POST 등)를 허용.addAllowedHeader("*")
: 모든 헤더를 허용.setAllowCredentials(true)
: 인증 정보(예: 쿠키)를 포함한 요청을 허용.configuration.addExposedHeader("Authorization")
를 하지 않으면 프론트 단에서 Authosization 값이 null로 표시돼서 추가하고 해결;
그 후에 CORS 설정을 httpSecurity
에 적용한다.
1
httpSecurity.cors((cors) -> cors.configurationSource(corsConfigurationSource()));
이로 인해 httpSecurity
는 클라이언트에서 오는 요청에 대해 CORS 정책을 체크하고 처리한다!
다음과 같이 Network
> Response Headers
에 잘 담긴 것을 확인할 수 있다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity httpSecurity) throws Exception {
httpSecurity.csrf((csrf) -> csrf.disable());
httpSecurity.sessionManagement((sessionManagement) ->
sessionManagement.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
);
httpSecurity.authorizeHttpRequests((authorizeRequest) ->
authorizeRequest
.requestMatchers("/api/users/login").permitAll()
.anyRequest().authenticated()
).cors((cors) -> cors.configurationSource(corsConfigurationSource()));
httpSecurity.addFilterBefore(jwtAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);
httpSecurity.addFilterAfter(jwtAuthorizationFilter(), JwtAuthenticationFilter.class);
return httpSecurity.build();
}
계속 httpSecurity.cors()로 해서 오류가 났었다..😓
This post is licensed under CC BY 4.0 by the author.