Published on

SpringSecurity + React 설정

SpringSecurity 적용기 (feat. SpringBoot3) 🥲

개발환경 세팅을 하고 react와 SpringBoot를 연동해서 CORS 설정까지 마쳤다. React와 Spring은 각각 3000번과 8080 포트로 실행하게 되는데, 두 개의 도메인은 포트가 다르기 때문에 SOP 문제가 발생된다. SOP란 간략하게 동일 출처 정책으로, 웹 애플리케이션은 자신의 출처와 동일한 리소스만 불러올 수 있게 하는 것이다. 그렇기 때문에 CORS를 허용해 주는 작업이 필요하다.

👉🏻 CORS란?


세팅 후 여차저차 SpringSecurity를 적용 후 회원가입을 시도하려는데,

const signUp = () => {
    axios.post('http://localhost:8080/memebers/joinProc', data)
        .then((response) => {
            setData(response.data);
        })
}

프론트단에서 위와 같은 api 호출 시 적용 전에는 나타나지 않더니 갑자기 아래와 같은 오류가 발생했다. 에러 코드 401, 요청 메서드 OPTION, prefilght에 집중!

image image image

SpringSecurity의 필터

스프링 시큐리티는 Filter로 구성되어 있다. 필터란 디스패처 서블릿(Dispatcher Servlet)에 요청이 전달되기 전, 후로 url 패턴에 맞는 요청에 대해 부가 작업을 할 수 있는 것이다. 대략적으로 어떠한 http 요청이 들어왔을 때 filter -> dispatcher servlet -> interceptor -> controller 순으로 처리가 된다. 그렇기 때문에 사용자 인증/인가를 위한 프레임워크인 스프링 스큐리티의 필터에서부터 걸러져 401 에러(유효한 인증 자격 증명이 없음)를 반환하는 것이다.

401은 알겠는데, Preflight Request은 뭘까? 🔍

prefilght request는 사전 요청을 의미한다. 실제 요청 전에 요청이 유효한지를 확인하기 위해 브라우저가 보내는 요청으로, OPTIONS 메서드를 사용한다. 확인 후에야 실제 요청이 진행되는 것이다! 즉 prefilght request가 이뤄지려면 서버에서 OPTIONS 메서드를 허용해 주어야 한다.

SpringSecurity 설정하기

  • gradle

스프링 시큐리티 적용을 위해 의존성을 먼저 추가해 주자.

implementation 'org.springframework.boot:spring-boot-starter-security'
  • SpringSecurity Config

HttpMethod.OPTIONS 메소드 허용시켜주기!

@Configuration
@EnableMethodSecurity
public class SpringSecurityConfig {

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
                .httpBasic().disable()
                .csrf().disable().cors().disable()
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)

                .and()
                .authorizeHttpRequests()
                .requestMatchers(HttpMethod.OPTIONS, "/**").permitAll() // Preflight Request 허용해주기
                .requestMatchers("/**").permitAll(); // 권한 상관(403 에러 방지)없이 모든 url 접근할 수 있도록 임시적으로 추가

        return http.build();
    }
}

👉🏻 설정 참고 블로그