음... 한마디로 말하자면 진짜 삽질했다...
우선 이건 내 회원가입 기능을 구현한 것이다.
@Slf4j
@RestController
@RequestMapping("/register")
@RequiredArgsConstructor
public class MemberRegisterController {
private final MemoryMemberService memberService;
@PostMapping("/create")
public ResponseEntity<BankMember> createMember(@Valid @RequestBody BankMemberDto bankMemberDto) throws CustomError {
log.info("회원 생성 요청 수신: {}", bankMemberDto);
try {
BankMember newMember = memberService.createBankMember(bankMemberDto, new HashSet<>(Set.of("USER"))); // 기본 역할로 USER 추가
log.info("회원 생성 성공: {}", newMember);
return ResponseEntity.ok(newMember);
} catch (CustomError e) {
log.error("회원 생성 실패: {}", e.getMessage(), e);
throw e; // 예외를 다시 던져서 상위 레벨에서 처리하도록 할 수 있습니다.
}
}
}
그리고 이건 SpringSecurity를 구현한 것이다.
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public BCryptPasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeHttpRequests(auth -> auth
// Publicly accessible URLs
.requestMatchers("/login**", "/home**", "/member/create").permitAll()
// URLs accessible by ADMIN and USER roles
.requestMatchers("/process", "/transaction/**", "/deposit/**", "/member/update/**", "/member/delete/**", "/account/**")
.hasAnyRole("ADMIN", "USER")
// URLs accessible by ADMIN role only
.requestMatchers("/admin/**").hasRole("ADMIN")
// Any other request requires authentication
.anyRequest().authenticated()
)
.formLogin(form -> form
.loginPage("/login") // 로그인 페이지 설정
.loginProcessingUrl("/perform_login") // 로그인 폼의 action URL
.defaultSuccessUrl("/home", true) // 로그인 성공 시 리디렉션할 URL
.failureUrl("/login?error=true") // 로그인 실패 시 리디렉션할 URL
.permitAll() // 로그인 페이지는 누구나 접근 가능
)
.logout(logout -> logout
.logoutUrl("/logout") // 로그아웃 URL
.logoutSuccessUrl("/login?logout=true") // 로그아웃 성공 시 리디렉션할 URL
.permitAll() // 로그아웃 URL은 누구나 접근 가능
);
return http.build();
}
}
구글링을 했을떄는 RequestMapping에 대한 경로가 잘못된 case들이 많아 나도 그런가? 싶었다. 그래서 여러 방법을 해봤지만 다 실패...
대부분들의 솔루션은@RequestMapping(value = "GetPost", method = RequestMethod.POST)를 추가 하라고 했다. 추가해봤지만 번번히 같은 오류를 반복했고, 포기하고 자려고했다.
자려고 하기 전에 해결 못한게 너무 아쉬워서 한번만 검색 해보자 라는 심정으로 검색...
진짜 감사하게도 참고해서 해결한 blog 나와 비슷한 오류를 발생하신 분을 보게 되었다.
2024-08-31T02:22:21.444+09:00 WARN 2569 --- [fintech_rebuilding] [nio-8080-exec-2] o.s.w.s.h.HandlerMappingIntrospector : Cache miss for REQUEST dispatch to '/register/create' (previous null). Performing CorsConfiguration lookup. This is logged once only at WARN level, and every time at TRACE.
2024-08-31T02:22:21.448+09:00 WARN 2569 --- [fintech_rebuilding] [nio-8080-exec-2] o.s.w.s.h.HandlerMappingIntrospector : Cache miss for REQUEST dispatch to '/register/create' (previous null). Performing MatchableHandlerMapping lookup. This is logged once only at WARN level, and every time at TRACE.
2024-08-31T02:22:21.487+09:00 ERROR 2569 --- [fintech_rebuilding] [nio-8080-exec-3] m.fintech.error.GlobalHandlerException : 지원되지 않는 HTTP 메서드 요청: Request method 'GET' is not supported
정확히는 이런 오류때문이다라고 하기 어렵지만, /register/create' (previous null) -> 값이 없다는 의미이다. 그렇다면 security 문제일까? 라는 생각을 다시 하게 되었고, 순간
.requestMatchers("/login**", "/home**", "/member/create").permitAll()
member로 설정했다는게 문득 생각이 들었다...
결국 해결!!!
혹시 저와 비슷한 문제를 경험하신다면 설정하신 securiy url을 한번만 check해 보세요. 그럼 저처럼 삽질을 면할 수도 있어요!