spring

[spring]spring security를 활용한 간단한 회원가입_1(feat.userDetails)

seulhasony 2023. 8. 17. 14:46

일단 의존성을 추가해주세요.

 

build.gradle

dependencies {
	implementation 'org.springframework.boot:spring-boot-starter-security'
}

1. member 엔티티 생성 (userDetail를 상속받은)

- username은 id로 활용

- roles은 회원마다 권한을 부여하기 위해 list로 선언(여러 권한을 가질 수 있음을 고려)

- spring 시큐리티에서 제공하는 userDetails를 상속받을 경우 아래 5가지의 메소드가 선언되어야 한다.

- 그중, getAuthorities메소드는 스프링 시큐리티에서 제공하는 권한 관련 기능을 활용하기 위해 SimpleGrantedAuthority와 매핑해줬다.

@Builder
@Getter
@ToString
@NoArgsConstructor
@AllArgsConstructor
@Entity(name = "MEMBER")
public class MemberEntity implements UserDetails {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String username;
    private String password;
    private List<String> roles;

    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        return this.roles.stream()
                .map(SimpleGrantedAuthority::new)
                //role 관련 기능을 활용하기 위해 SimpleGrantedAuthority와 매핑해준다.
                .collect(Collectors.toList());
    }

    @Override
    public boolean isAccountNonExpired() {
        return false;
    }

    @Override
    public boolean isAccountNonLocked() {
        return false;
    }

    @Override
    public boolean isCredentialsNonExpired() {
        return false;
    }

    @Override
    public boolean isEnabled() {
        return false;
    }
}

2. config 파일을 생성해, 보안을 위한 패스워드 암호화 bean을 생성해준다.

@Configuration
public class AppConfig {

    @Bean
    public PasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
    }
    
}

 

3. 로그인 및 회원가입을 위한 service 클래스를 생성해준다.

@Slf4j
@Service
@AllArgsConstructor
public class MemberService implements UserDetailsService {

    private final MemberRepository memberRepository;
    private PasswordEncoder passwordEncoder;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        //UserDetailsService 상속시, 필수 메소드
        return memberRepository.findByUsername(username)
                            .orElseThrow(()->new AlreadyExistUserException());

    }

	/* 회원 가입 */
    public MemberEntity register(Auth.register member){
        if(memberRepository.existsByUsername(member.getUsername())){
            throw new AlreadyExistUserException();
        }

        //패스워드 암호화 후 회원정보 DB저장
        member.setPassword(passwordEncoder.encode(member.getPassword()));
        MemberEntity memberEntity = memberRepository.save(member.toEntity());

        return memberEntity;
    }

	/* 회원정보 확인 */
    public MemberEntity authentication(Auth.login member){
        MemberEntity memberEntity = memberRepository.findByUsername(member.getUsername())
                                .orElseThrow(()-> new RuntimeException("존재하지 않는 아이디입니다."));
		
        //암호화된 패스워드와 비교를 위한 matches메소드 활용
        if(!passwordEncoder.matches(memberEntity.getPassword(),member.getPassword())){
            throw new RuntimeException("비밀번호가 틀립니다.");
        }
        
        return memberEntity;
    }
}