처음에 아이디 패스워드 체크를 구현하려고 했는데 이상하게 잘 되지 않았다.
'아니 왜 이게 계속 로그인이 되는 거지? 나는 로그인 하는 기능을 구현한 적이 없는데...?' 보니까 내가 Spring Security를 이용해서 로그인을 진행했다. 그러니 일반적으로 아이디 패스워드 체크를 구현하려고 하니 계속 진행이 되지 않았다.
그럼 어떻게 해야할까? 고민을 하다가 이건 내가 절대 생각만으로는 안되는 부분이구나라고 느껴서 바로 구글에 검색해보니 failureHandler를 등록해서 진행하는 방법이 있더라.
@Configuration
@EnableWebSecurity
//@EnableGlobalMethodSecurity(prePostEnabled = true)
@RequiredArgsConstructor
public class SecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeRequests()
.antMatchers("/", "/signin/**", "/signup",
"/auth/**", "/chungCompany", "/estimates/**",
"/items/**" ,"/review/**" ,"/admin/**", "/api/**", "/image/**", "/order/**" )
.permitAll()
.anyRequest()
.authenticated()
.and()
.formLogin()
// .usernameParameter("userId")
.loginPage("/signin")
.loginProcessingUrl("/auth/loginProc")
.failureHandler(customFailureHandler)
.defaultSuccessUrl("/");
return http.build();
}
}
failureHandler부분에 customFailureHandler를 등록해주면 되더라.
package com.project.blueshirt.config.handler;
import java.io.IOException;
import java.net.URLEncoder;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler;
import org.springframework.stereotype.Component;
@Component
public class CustomAuthFailureHandler extends SimpleUrlAuthenticationFailureHandler{
@Override
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response,
AuthenticationException exception) throws IOException, ServletException {
String errorMessage = "";
if(exception instanceof BadCredentialsException) {
errorMessage = "아이디 또는 비밀번호가 맞지 않습니다. 다시 확인해 주세요";
} else if(exception instanceof UsernameNotFoundException) {
errorMessage = "계정이 존재하지 않습니다. 회원가입 진행 후 로그인 해주세요";
}
errorMessage = URLEncoder.encode(errorMessage, "UTF-8");
setDefaultFailureUrl("/signin?error=true&exception="+ errorMessage);
super.onAuthenticationFailure(request, response, exception);
}
}
PageController
@Slf4j
@Controller
@RequiredArgsConstructor
public class MemberPageController {
@GetMapping("/signin")
public String SignInPage(@RequestParam(value = "error", required = false) String error,
@RequestParam(value = "exception", required = false) String exception,
Model model) {
model.addAttribute("error", error);
model.addAttribute("exception", exception);
return "page/member/signin";
}
}
결과값은
아이디를 입력하지 않거나, 패스워드를 입력하지 않았을때, 혹은 아이디나 패스워드를 틀리게 입력했을 때 해당 문구가 나오도록 구현했다. 생각해보니까 조금 더 유저를 생각해서 만든다면 아이디 패스워드를 입력하지 않았을 때는 아이디, 패스워드를 입력해주세요라고 나오는 게 맞다고 본다. 이 부분은 또 좀 더 프로젝트를 다듬으면서 고쳐나가도록 하자.
※ 문득 드는 생각.
Controller에 보면 @RequestParam을 쓴다. 왜 @RequestParam을 쓸까?라고 문득 블로그를 작성하면서 생각을 해본다. 보면
이렇게 URL에 Error메시지가 등록되는 걸 볼 수 있다. 그렇다면 이 SpringSecurity에 등록한 customFailureHandler는 Controller에 도착하기 전에 Servelt? 단계라고 하나 filter? 이 부분에서 먼저 체크가 들어간다는 소리가 된다.
이런식으로 말이다. 정확한 건 좀 더 공부가 필요해 보이나 내가 생각해봤을 때는 이렇게 작동하는 것이 맞다고 본다. 근데 조금 번거로워 보이기도 하다. 굳이 filter에서 다시 클라이언트로 보내서 다시 controller로 요청을 보내는 것이 맞는가? 그냥 Controller에서 입력값 에러를 감지해서 처리하는 게 더 효율적이지 않나라고 생각해본다.
혹시 고수님들이 이걸 보시면 따끔한 지적 부탁드립니다~
'Spring' 카테고리의 다른 글
Spring에서 받아온 Validation Error메시지를 Javascript를 활용해서 화면에 보여주기(BlueShirt Project) (2) | 2023.10.25 |
---|---|
SpringSecurity를 적용한 로그인시 상단 메뉴 변경(Spring - BlueShirt Project) (0) | 2023.10.24 |
내 생각으로 구현해 보는 간단한 아이디 찾기(Spring - BlueShirt Project) (0) | 2023.10.20 |
Could not find or load Main class 오류 - IntelliJ (0) | 2023.05.12 |
SecurityConfig 설정 - SpringSecurity (0) | 2023.02.15 |