[Start Spring Boot] Spring Security JPA로 User 관리하기

·2024년 4월 11일
0

Start Spring Boot!

목록 보기
38/53
post-thumbnail

DB로 User 관리하기

다음과 같은 과정으로 진행한다.

  • User Entity, DTO 생성
  • UserRepository, UserService 구현
  • UserRole 이해하기
  • UserDetailsService을 이용하여 UserSecurityService를 구현하여 인증하기

User Entity, DTO

Entity

  • User를 클래스명으로 사용하면 안됨!
  • SiteUser.java
package com.chan.ssb.user;

import jakarta.persistence.*;

@Entity
public class SiteUser {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private long id;
    @Column(unique = true)
    private String username;
    private String password;
    private String role;

}
  • username에 unique을 사용해서 고유하게 만들었다.
  • username에 중복이 발생 시 예외가 발생한다.

DTO

  • SiteUserDTO.java
package com.chan.ssb.user;

public class SiteUserDTO {

    private long id;
    private String username;
    private String password;
    private String role;

}

Repository, Service

Repository

  • UserRepository.java
package com.chan.ssb.user;

import org.springframework.data.jpa.repository.JpaRepository;

import java.util.Optional;

public interface UserRepository extends JpaRepository<SiteUser, Long> {
    Optional<SiteUser> findByusername(String username);
}

Service

  • UserService.java
package com.chan.ssb.user;

import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

@Service
public class UserService {
    private final UserRepository userRepository;
    private final PasswordEncoder passwordEncoder;

    public UserService(UserRepository userRepository, PasswordEncoder passwordEncoder) {
        this.userRepository = userRepository;
        this.passwordEncoder = passwordEncoder;
    }

    public SiteUserDTO createSiteUser(SiteUserDTO siteUserDTO) {
        SiteUser siteUser = new SiteUser(siteUserDTO.getId(), siteUserDTO.getUsername(), passwordEncoder.encode(siteUserDTO.getPassword()), siteUserDTO.getRole());
        SiteUser savedUser;

        try {
            savedUser = userRepository.save(siteUser);
        } catch (DataIntegrityViolationException e) {
            throw new IllegalArgumentException("Username already exists");
        } catch (Exception e) {
            throw new IllegalArgumentException("An error occurred while saving the user");
        }

        return SiteUserDTO.fromEntity(savedUser);
    }
}
  • Unique이기 때문에 중복 시 오류가 발생한다.
  • IllegalArgumentException: 중복 시 발생

User Role

What is?

  • Spring Security는 인증뿐 아니라 권한도 관리한다. 즉, 인증 후 권한을 부여해야한다.
  • ROLE_USER, ROLE_ADMIN

Use

  • 따로 Enum을 구성하여 사용
  • 문자열을 DB에 저장(ROLE_ADMIN)

UserDetailsService

UserDetails?

  • Spring Security에서 사용자의 정보를 담는 인터페이스
  • Username, Password를 가진다.
  • 기본 UserDetails로는 모든 정보를 담을 수 없기 때문에 CustomUserDetails 구현해서 사용한다.

UserDetailsService?

  • Spring Security에서 유저의 정보를 가져오는 인터페이스

UserSecurityService

  • UserSecurityService.java
package com.chan.ssb.user;

import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

@Service
public class UserSecurityService implements UserDetailsService {

    private final UserRepository userRepository;

    public UserSecurityService(UserRepository userRepository){
        this.userRepository = userRepository;
    }

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        Optional<SiteUser> _siteUser = this.userRepository.findByusername(username);
        if (_siteUser.isEmpty()) {
            throw new UsernameNotFoundException("User not found");
        }
        SiteUser siteUser = _siteUser.get();
        List<GrantedAuthority> authorities = new ArrayList<>();
        authorities.add(new SimpleGrantedAuthority(siteUser.getRole()));
        return new User(siteUser.getUsername(), siteUser.getPassword(), authorities);

    }
}
  • loadUserByUsername를 반드시 구현해야한다!
  • GrantedAuthority: 사용자 권한
  • SimpleGrantedAuthority: 권한을 구현하는 간단한 방법으로 ROLE_USER, ROLE_ADMIN을 인자로 받아 권한을 생성함
  • User을 만들어서 반환한다.

profile
백엔드 개발자가 꿈인 컴공과

0개의 댓글

관련 채용 정보