프로젝트/SNS 프로젝트
[로그인] UserDetailService
영카이브
2024. 3. 28. 02:04
로그인할 때 POST방식 쓰는이유?
<form class="login__input" action="/auth/signin" method="POST">
<input type="text" name="username" placeholder="유저네임" required="required" />
<input type="password" name="password" placeholder="비밀번호" required="required" />
<button>로그인</button>
</form>
POST는 보통 INSERT할 때 쓰지만 예외적으로 로그인은 DB에 해당 정보를 SELECT하는 것임에도 보안해야 할 사용자의 개인 정보를 서버에 전달하는 과정이기 때문에 body에 담아 전송하는 POST방식을 택한다. 따라서 URL에 정보가 노출되지 않는다.
PrincipalDetailsService
PrincipalDetailsService 클래스는 Spring Security에서 사용자의 인증 정보를 조회하는 역할을 한다. 주로 사용자의 아이디(username)를 기반으로 데이터베이스에서 사용자 정보를 조회하고, 조회된 정보를 PrincipalDetails 객체로 변환하여 반환한다.
@RequiredArgsConstructor
@Service
public class PrincipalDetailsService implements UserDetailsService{
private final UserRepository userRepository;
// 1. 패스워드는 알아서 체킹하므로 신경쓸 필요 없다.
// 2. 리턴이 잘되면 자동으로 UserDetails타입을 세션이 만든다.
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User userEntity =userRepository.findByUsername(username);
if(userEntity==null) {
// 사용자 정보가 없는 경우 예외 처리
throw new UsernameNotFoundException(username + " not found");
} else {
// 사용자 정보가 있는 경우 PrincipalDetails 반환
// return userEntity;
return new PrincipalDetails(userEntity);
}
}
}
- 사용자가 /auth/signin 엔드포인트로 POST 요청을 보낸다.
- 시큐리티 설정 파일(SecurityConfig)은 이러한 요청이 발생하는지 지속적으로 감시하고 있다.
- POST 방식으로 /auth/signin 요청이 발생하면 시큐리티 설정 파일이 해당 요청을 인식하고 처리한다.
- 시큐리티 설정 파일은 HTTP 요청의 body에서 username과 password를 추출한다.
- 추출된 username과 password는 IoC컨테이너의 메모리에 미리 등록되어 있는 UserDetailsService로 전달된다.
- UserDetailsService는 Spring Security에서 제공하는 인터페이스를 구현한 클래스다. 이 클래스는 사용자의 인증 정보를 조회하고 제공한다.
- PrincipalDetailsService는 @Service 어노테이션이 붙어 있으므로 IoC 컨테이너에 자동으로 등록된다.
- UserDetailsService와 PrincipalDetailsService는 동일한 부모 타입을 가지며, PrincipalDetailsService는 UserDetailsService를 구현한 구체적인 구현체다. 따라서 PrincipalDetailsService가 UserDetailsService의 메서드를 오버라이딩하여 사용자의 로그인을 처리한다.
- 로그인 과정에서는 PrincipalDetailsService에서 사용자의 인증 정보를 기반으로 인증을 수행하고, 성공할 경우 인증된 사용자 객체를 반환한다.
* username만 매개변수로 받는 이유는 password에 대한 처리는 Spring Security에서 자동으로 이루어진다. 따라서 loadUserByUsername 메서드에서는 사용자의 username만을 매개변수로 받고, Spring Security가 내부적으로 username에 해당하는 사용자의 정보를 조회하고 해당 사용자의 비밀번호를 검증한다. 이렇게 하면 개발자는 별도의 비밀번호 검증을 구현할 필요 없이 Spring Security가 제공하는 기능을 활용하여 간단하게 사용자 인증을 처리할 수 있다.