[SpringBoot/React] React + Spring Boot 연동 시 로그인 세션 유지가 안 될 때 해결 방법 (with Spring Security)

gyeol·2025년 4월 11일
post-thumbnail

프로젝트를 진행하던 중 React와 Spring Boot를 연동해서 로그인 기능을 구현하려 했는데, 로그인은 성공했지만, 이후 마이페이지 API(/api/myPage/info) 요청 시 항상 401 Unauthorized가 떨어졌다.

axios.post('http://localhost:8080/api/member/login', data, {
  withCredentials: true,
  headers: { 'Content-Type': 'application/json' }
});

쿠키도 잘 저장됐고, JSESSIONID도 브라우저에 보였지만,
다음 요청에서 서버는 항상 principal == null로 판단하고 401을 반환했다.


해결 방법

1. 로그인 후 SecurityContext에 저장

session.setAttribute("SPRING_SECURITY_CONTEXT", SecurityContextHolder.getContext());

이걸 넣어줘야 Spring Security가 이후 요청에서 로그인 상태로 인식한다.

2. 여러 개의 SecurityFilterChain 생성

알고보니 Spring Security 5.7이상부터는 여러 개의 SecurityFilterChain을 만들 수 있다는 거였다. 이걸 알고나니 문제 해결이 수월해졌다. 리액트는 api/ 경로로 요청을 하기에 나는 .securityMatcher("/api/**") 을 적어준 뒤 그에 맞는 csrf, cors 로직을 짰다.

@Order(1)
@Bean
public SecurityFilterChain apiSecurity(HttpSecurity http) {
    http.securityMatcher("/api/**")
        .authorizeHttpRequests(auth -> auth.anyRequest().permitAll())
        .formLogin(form -> form.disable());
    return http.build();
}

@Order(2)
@Bean
public SecurityFilterChain webSecurity(HttpSecurity http) {
    http.authorizeHttpRequests(auth -> auth.anyRequest().authenticated())
        .formLogin(...) // 웹 로그인용
    return http.build();
}

정리하며

이번 문제는 정말 많은 사람들이 겪는 이슈다.
React와 Spring Security를 연동하려면 단순히 CORS만 해결하는 게 아니라,
세션과 SecurityContext까지 어떻게 연결되는지를 정확히 이해해야 인증이 유지된다.

profile
공부 기록 공간 '◡'

0개의 댓글