프로젝트 중 로그인 관련해서 마주친 오류에 대한 내용 정리입니다.
마주친 오류는 다음과 같습니다.
해당 오류가 발생한 원인
발생한 원인은 로그인 로직 수정 때문이었습니다.
수정 전 로그인 방식
- 이메일, 비밀번호 입력해서 로그인
수정 후 로그인 방식
- 아이디, 비밀번호 입력해서 로그인
오류 발생 위치
기존 로그인 과정 코드에서, 이슈가 발생한 부분은 다음과 같습니다.
Authentication authentication = authenticationManagerBuilder.getObject().authenticate(usernamePasswordAuthenticationToken);
UsernamePasswordAuthenticationToken으로 생성한 토큰을 넘겨 권한 인증을 받는 부분입니다.
이 부분 수정 후 오류가 발생했으니, 수정한 부분이 문제가 되는 것 같습니다.
직접 로그에 찍힌 부분들을 따라가며 원인을 찾아봤습니다.
실행 순서
AuthenticfationManager 인터페이스의 authenticate입니다.
인터페이스니, 당연히 구현체 중 하나가 실행이 될텐데, 오류 로그에 providerManager를 통해 이 구현체의 authenticate가 실행된다는 것을 알 수 있었습니다.
여기서, 마지막 줄이 오류 발생부분입니다. provider.authenticate(authentication)이 바로 그것이다. 이 메서드를 또 ctrl + b를 통해 찾아보면...
AuthenticationProvider가 등장합니다.여기 안에 작성되어 있는 authenticate가 동작한 것입니다.
물론 이것도 인터페이스니, 자세한 내용은 구현체를 찾아야 합니다.
구현체는 오류 로그에도 나와있듯 AbstractUserDetailsAuthenticationProvider입니다.
밑줄 친 부분의 retrieveUser입니다. BadCredentialsException이 발생했었으니, try 안의 해당 부분이 문제였습니다.
retrieveUser를 또 들여다보면 다음과 같습니다.
retreieveUser에서 UserDetails를 사용하는 모습을 볼 수 있습니다.
여기서 UserDetailsService의 loadUserByUsername을 사용할 때, 조건에 맞는 UserDetails를 찾지 못해 에러가 발생한 것! 즉, UserDetailsService의 loadUserByUsername에 문제가 있었다!
까먹고 loadUserByUsername 메서드에서 아이디가 아니라 이메일로 여전히 사용자를 찾게 되어있는 걸 수정하지 못했게 문제였습니다 ㅎㅎ... 개고생
여기를 수정하니, 성공적으로 로그인이 진행되네요. 다행히 금방 찾을 수 있었습니다.
알게된 것
authenticationManagerBuilder의 getObject().authenticate 메서드는 내부적으로 UserDetailsService의 loadUserByUsername 메서드를 호출해 사용자를 찾는다는 것을 알게되었습니다.
시간이 없다면 역시 중단점 디버깅이 빠를텐데.. 궁금증 때문에 어떤 과정을 통해 도달하는지 궁금해 이렇게 삽질을 했네요. 촉박한 상황이면 이렇게 하지 말아야 겠습니다 ㅜ
'Project > 9uin' 카테고리의 다른 글
spring boot 사이드 프로젝트: DockerFile, docker-compose.yml 작성 및 클라우드 세팅(GCP) 2 (0) | 2023.10.30 |
---|---|
spring boot 사이드 프로젝트: DockerFile, docker-compose.yml 작성 및 클라우드 세팅(GCP) 1 (0) | 2023.10.30 |
spring boot 사이드 프로젝트 : spring boot + github action을 통해 CI/CD구축 (0) | 2023.10.29 |
springboot 사이드 프로젝트[9] : controller 작성 (0) | 2023.09.04 |
spring boot 사이드 프로젝트[8] : 게시글 태그 필터링 (querydsl join) (0) | 2023.06.14 |