구조도
본 연습용 프로젝트는 JWT를 사용하지 않았고, 최대한 간단한 로직만을 사용하였습니다.
유저 네임(아이디)의 유니크 설정
@Column(unique = true) private String username; //아이디엔티티에서 유저 아이디에 unique설정을 해준다.
중복 가입 방지 로직
먼저, repository에 existsBy문으로 해당 아이디가 존재하는지 확인하는 메소드를 추가한다.
public interface UserRepository extends JpaRepository<UserEntity, Long> { boolean existsByUsername(String username); }이후 해당 메소드를 사용하여 서비스단에서 중복 가입 방지 로직을 추가한다.
public void joinProcess(JoinDto joinDto){ //db에 동일한 username이 존재하는지 검증 boolean isUser=userRepository.existsByUsername(joinDto.getUsername()); if(isUser) return; //존재시 return(exception발생시켜야함) //이후 회원저장로직 UserEntity user=new UserEntity(); user.setUsername(joinDto.getUsername()); user.setPassword(bCryptPasswordEncoder.encode(joinDto.getPassword())); //비밀번호 암호화 후 저장 user.setRole("ROLE_USER"); //유저의 권한 지정 userRepository.save(user); }UserDetailsService 구현
Spring Security에서 유저의 정보를 가져오는 인터페이스이다.
loadUserByUsername 메소드를 오버라이딩 해주어야 한다.@Service public class UserDetailsServiceImpl implements UserDetailsService { @Autowired private UserRepository userRepository; @Override //로그인시 security config가 검증을 위하여 username을 넣어서 보낸다. public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { UserEntity user=userRepository.findByUsername(username); if(user!=null){ return new CustomUserDetails(user); } return null; } }UserDetails 구현
Spring Security에서 사용자의 정보를 담는 인터페이스로, 사용자의 정보를 구현하기 위하여 구현해야 한다.
etAuthorities() Collection<? extends GrantedAuthority>
getPassword()
getUsername()
isAccountNonExpired()
isAccountNonLocked()
isCredentialsNonExpired()
isEnabled()
메소드들을 오버라이딩해야 한다.public class CustomUserDetails implements UserDetails { private UserEntity user; public CustomUserDetails(UserEntity user){ this.user=user; } @Override public Collection<? extends GrantedAuthority> getAuthorities() { //사용자의 권한 리턴(role값) Collection<GrantedAuthority> collection=new ArrayList<>(); collection.add(new GrantedAuthority() { @Override public String getAuthority() { return user.getRole(); } }); return collection; } @Override public String getPassword() { return user.getPassword(); } @Override public String getUsername() { //여기서 username은 PK로 지정하여야 한다.(중복이 아예 불가능한 필드인) return user.getUsername(); } @Override public boolean isAccountNonExpired() { //사용자 계정이 만료되었는지 - true : 만료 안됨 return true; } @Override public boolean isAccountNonLocked() { //사용자가 잠겨있는지 - true : 안잠김 return true; } @Override public boolean isCredentialsNonExpired() { //자격(비밀번호) 증명 만료 여부 -true: 만료안됨 return true; } @Override public boolean isEnabled() { //사용자의 사용 가능 여부 : true : 사용가능 return true; } }Security Config에서 사용자의 정보를 UserDetailsService를 통하여 불러올 때, 유저의 정보를 감싸고 있는 DTO의 역할을 하는 것이 UserDetails이다.
Reference