JavaScript -> RestController POST 통신 오류

2025. 4. 24. 23:54Java/Spring

Spring Boot 프로젝트를 하던 도중 프론트-백 분리 구조를 활용해서 코드 작성 중 이유를 알 수 없는 오류가 발생하고 있었습니다

그 어떤 로그도 안 찍히길래 뭔 문제인가... 하루를 고민했는데 해결방법을 찾았습니다.

 

1. 오류의 원인

일단, 문제가 뭐였냐면 javascript 단에서 ajax로 post url 요청을 controller 쪽으로 하는 상황이었는데, 회원가입 성공을 했을 경우 요청이 controller쪽에 닿지도 못하는 문제가 발생했었습니다. 근데 이게 로그도 찍히는 게 아니고.. 오류 문구도 없으니까 도대체 뭐가 문제인지를 몰랐었는데.. javascript 코드 쪽은 문제가 없어 보였습니다. (아래는 제 프로젝트의 js 코드입니다.)

$.ajax({
    type: "POST",
    url: "/api/register",
    data: JSON.stringify(data),
    contentType: "application/json",

    success: function (result) {
        alert("회원가입이 완료되었습니다.");
        window.location.href = "/login";
    },
    error: function (request, status, error) {
        alert("회원가입 오류\n code: " + request.status + "\n error: " + error);
    }
});

 

그렇다고 controller쪽 코드도? 문제가 될 게 없었습니다. 솔직히 어려운 로직이 아니었거든요.

@PostMapping("/register")
public ResponseEntity<String> register(@RequestBody UserDto userDto) {
    String encodedPwd = passwordEncoder.encode(userDto.getPwd());
    userDto.setPwd(encodedPwd);
    try {
        userService.register(userDto);
        return ResponseEntity.ok("success");
    } catch (Exception e) {
        return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("Register Fail: " + e.getMessage());
    }
}

 

그렇게 쩔쩔 매다가 Spring Security 설정 쪽의 filterChain 문제가 있는건가 해서 확인해봤는데, 이곳에 원인이 있었습니다. 뭐 때문인지 알 것 같으신가요?

@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
    http.csrf(csrf -> csrf.disable())
            .authorizeHttpRequests(
                    auth -> auth.requestMatchers("/", "/login", "/register", "/main", "/api/overlap/**").permitAll().anyRequest().authenticated())
            .formLogin(form -> form.loginPage("/login").loginProcessingUrl("/login")
                    .defaultSuccessUrl("/main", true).permitAll()
                    .failureHandler((request, response, exception) -> {
                        System.out.println("로그인 실패 : " + exception.getMessage());
                        response.sendRedirect("/login?error");
                    }))
            .logout(logout -> {
                logout.logoutSuccessUrl("/login");
                logout.deleteCookies("JSESSIONID", "remember-me"); // 로그아웃 시 쿠기 삭제
            });

    System.out.println("필터 체인 로그");

    return http.build();
}

 

2. 오류 해결

기본적으로 Spring Security를 활용해서 로그인, 회원가입을 구현하게 될 경우에는 특정 URL의 접근 권한을 설정해줘야합니다. 이를 안해주면 Security쪽에서 아예 막아버려요. 이를 설정하는 메서드가 무엇이냐면 requestMatchers 메서드입니다.

근데 지금 Security쪽 코드를 보시면 제가 회원가입 요청을 하는 URL의 접근 경로는 허용이 되어있지 않습니다. (아예 포함이 안되어있기 때문) 그렇기 때문에 이것을 추가해준다면 해결이 될 것입니다..

@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
    http.csrf(csrf -> csrf.disable())
            .authorizeHttpRequests(
                    auth -> auth.requestMatchers("/", "/login", "/register", "/main", "/api/**").permitAll().anyRequest().authenticated())
            .formLogin(form -> form.loginPage("/login").loginProcessingUrl("/login")
                    .defaultSuccessUrl("/main", true).permitAll()
                    .failureHandler((request, response, exception) -> {
                        System.out.println("로그인 실패 : " + exception.getMessage());
                        response.sendRedirect("/login?error");
                    }))
            .logout(logout -> {
                logout.logoutSuccessUrl("/login");
                logout.deleteCookies("JSESSIONID", "remember-me"); // 로그아웃 시 쿠기 삭제
            });

    System.out.println("필터 체인 로그");

    return http.build();
}

 

어차피 상위 url은 비슷하니 "/api/**" 로 두 개 다 포함시켰습니다.

 

 

생각해보면 되게 당연한 문제였는데, Spring Security에 대한 이해도가 부족한 상태에서 개발을 하다보니 이런 문제가 발생한 것 같습니다. 어떤 라이브러리, api, 프레임워크를 사용할 때는 해당 기술을 이해하고 사용하는 것이 중요한 것 같습니다.

 

그나저나 controller쪽에 setPwd 메서드가 좀 거슬리네요.. 이번 문제 해결했으니 저런 더러운 코드나 바꿔야겠습니다 ㅎㅎ..