BE/Spring-Boot
[SpringBoot] Spring Security + React CORS 문제 해결
suhyeon chae
2023. 7. 8. 23:23
--- 기존 설정들
}
,
"proxy": "http://localhost:8080",
"devDependencies": {
"@types/js-cookie": "^3.0.3",
"@types/styled-components": "^5.1.26"
}
기존에 spring에서 설정해서 잘 됐던 문제가 spring security를 적용하니 react와 spring간 cors 문제가 발생하여 통신이 안되는 오류가 있었다.
기존 설정
기존 React와 통신하기 위한 설정 코드
@Configuration
@RequiredArgsConstructor
public class WebMvcConfig implements WebMvcConfigurer {
private final long MAX_AGE_SECS = 3600;
@Override
public void addCorsMappings(CorsRegistry registry) {
// 모든 경로에 대해
registry.addMapping("/**")
// Origin이 localhost:3000에 대해
.allowedOrigins(
"http://localhost:3000"
)
// GET, POST, PUT, PATCH, DELETE, OPTIONS 메서드를 허용한다.
.allowedMethods("GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS")
.allowedHeaders("*")
.allowCredentials(true)
.maxAge(MAX_AGE_SECS);
}
}
해결 방안
1. react package.json에 proxy 설정
// 기존 설정들
},
"proxy": "http://localhost:8080",
"devDependencies": {
"@types/js-cookie": "^3.0.3",
"@types/styled-components": "^5.1.26"
}
2. security config 파일에 아래 코드 추가
// 인증이 필요한 페이지
.requestMatchers(HttpMethod.OPTIONS, "/**").permitAll()
// 전체 코드
@Configuration
@RequiredArgsConstructor
public class SecurityConfig {
private final JwtTokenProvider jwtTokenProvider;
@Qualifier("customAuthenticationEntryPoint")
private final AuthenticationEntryPoint authEntryPoint;
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder(); // JWT를 사용하기 위해서는 기본적으로 password encoder가 필요한데, 여기서는 Bycrypt encoder를 사용했다.
}
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.httpBasic().disable()
.csrf().disable() // rest api이므로 basic auth 및 csrf 보안을 사용하지 않는다는 설정이다.
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS) // JWT를 사용하기 때문에 세션을 사용하지 않는다는 설정이다.
.and()
.authorizeHttpRequests(requests -> requests
// 인증이 필요한 페이지 (이 부분 추가)
.requestMatchers(HttpMethod.OPTIONS, "/**").permitAll()
.requestMatchers("/design/**").authenticated()
.anyRequest().permitAll())
.exceptionHandling()
.authenticationEntryPoint(authEntryPoint)
.and()
.addFilterBefore(new JwtAuthenticationFilter(jwtTokenProvider), UsernamePasswordAuthenticationFilter.class); // JWT 인증을 위하여 직접 구현한 필터를 UsernamePasswordAuthenticationFilter 전에 실행하겠다는 설정이다
return http.build();
}
}