🏕️상황
- 강의를 따라 하던 중에 회원가입은 정상적으로 작동했으나 '로그인'에서 로그인이 되지 않고 아래의 사진처럼 오류가 발생했다.
- 미쳐버릴 지경이었다.
콘솔에는 아무런 오류도 찍히지 않고, 심지어 두 번째 사진처럼 사용자 정보도 굉장히 잘 찾아지는데 왜 로그인만 안 되는지 답답하고, 막막했다. 진짜로 두 번째 사진처럼 콘솔에는 아무런 오류도 없었다.
💦과정
1. 관련이 있는 클래스들을 돌아다니며 코드를 수정해보았지만 무용지물....
2. WebSecurityConfigurerAdapter의 deprecated로 인한 코드 수정....
- 강의에서는 WebSecurityConfigurerAdapter를 사용하여 코드상에 해당 부분에 줄이 그어져 있는(deprecated) 상황이었다.
- 그래서 검색해보니 인프런에서 알려준 방법을 사용하는 것이 최신 버전인 거 같아서 내 코드와 합쳐 수정해 보았다.
- 더 나은 방향으로 진행한 것은 맞지만 에러가 해결되지는 않았다.
3. 에러에 대응하는 핸들러 클래스를 만들어 원인 찾아보기
@Component
public class UserLoginFailHandler 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 InternalAuthenticationServiceException) {
errorMessage = "내부적으로 발생한 시스템 문제로 인해 요청을 처리할 수 없습니다. 관리자에게 문의하세요.";
} else if (exception instanceof UsernameNotFoundException) {
errorMessage = "계정이 존재하지 않습니다. 회원가입 진행 후 로그인 해주세요.";
} else if (exception instanceof AuthenticationCredentialsNotFoundException) {
errorMessage = "인증 요청이 거부되었습니다. 관리자에게 문의하세요.";
} else {
errorMessage = "알 수 없는 이유로 로그인에 실패하였습니다 관리자에게 문의하세요.";
}
errorMessage = URLEncoder.encode(errorMessage, "UTF-8");
setDefaultFailureUrl("/auth/loginForm?error=true&exception=" + errorMessage);
super.onAuthenticationFailure(request, response, exception);
}
}
- 하지만 슬프게도 (아래의 사진처럼) 맨 마지막 오류 메시지가 나왔다.
- 그 말은 즉, 또 원인을 정확히 파악할 수 없는 말이다.
이렇게 했을 때 오류를 잡지는 못했다... 실패....
🗝️해결
그런데 자세히 생각해 보니 해결의 방법을 찾을 수 있었다.
- 오류 핸들러를 작성하니 맨 처음에 있던 오류 url보다 한 단계 더 자세하게 나와있게 되었고, /auth/라는 경로가 나와있었다.
- 그래서!! auth라는 폴더 경로 아래에 있는 클래스 중에 하나가 문제라고 생각이 들었고, 그 파일들만 분석해 보게 되었다.
// PrincipalDetailsService 클래스
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
System.out.println("username : " + username);
User user = userRepository.findByUsername(username);
if (user == null) {
throw new UsernameNotFoundException("사용자를 찾을 수 없습니다: " + username);
}
// 사용자 정보를 UserDetails 객체로 변환
return new org.springframework.security.core.userdetails.User(
user.getUsername(),
user.getPassword(),
// 권한 설정 (필요에 따라 변경)
Arrays.asList(new SimpleGrantedAuthority("ROLE_USER"))
);
}
- 1차적으로 이렇게 코드를 구성했을 때 로그인에 성공할 수 있었다...
- 하지만 UserDetails를 구현한 클래스를 저렇게 생짜로 return 값으로 주는 것은 말이 안 된다고 생각하여 근본적인 원인을 찾으려고 했다.
- 이미 이렇게 UserDetails를 구현한 클래스가 존재하는데... 이 클래스를 반드시 활용하면서도 성공할 방법을 고민하였다.
UserDetails를 구현한 클래스에 @Data를 붙이지 않아서 로그인이 그렇게 지독하게 되지 않았던 것이다...
'개발공부 > spring security & JWT 강의' 카테고리의 다른 글
[6강] 구글 로그인 준비 (0) | 2023.09.22 |
---|---|
[5강] 메소드 단위로 권한 설정하기 - @Secured (0) | 2023.09.21 |
[3강][4강] spring security 회원가입/로그인 (1) | 2023.09.16 |
[2강] spring security 설정 (예제) (0) | 2023.09.15 |
[1강] spring security 환경설정 &⭐새로운 사실 (0) | 2023.09.15 |