Spring/[P] 도서 대여 프로그램

🩵 Spring Security (2) 로그인 🩵

alsruds 2023. 11. 28. 05:10
📺스프링 시큐리티 강의📺
https://www.youtube.com/playlist?list=PLJkjrxxiBSFCKD9TRKDYn7IE96K2u3C3U

 

  • ⭐ UserDetailService & UserDetails 기능 사용하기

 

🫧 Web 으로 확인하기

· CustomUserDetailService

@Service
@RequiredArgsConstructor
public class CustomUserDetailService implements UserDetailsService {

    private final MemberRepository memberRepository;

    @Override
    public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException {
        Member savedMember = memberRepository.findByEmail(email);

        if (savedMember != null) { // 저장된 회원이 있음
            return new CustomUserDetail(savedMember);
        }
        return null;
    }
}

 

· CustomUserDetail

public class CustomUserDetail implements UserDetails {

    private Member member;

    public CustomUserDetail(Member member) {
        this.member = member;
    }

    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        // 회원 role 값 반환
        /*
        Collection<GrantedAuthority> collection = new ArrayList<>();
        collection.add(new GrantedAuthority() {
            @Override
            public String getAuthority() {
                return member.getRole();
            }
        });
        return collection;
         */

        return null;
    }

    @Override
    public String getPassword() {
        return member.getPassword();
    }

    @Override
    public String getUsername() {
        return member.getEmail();
    }

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

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

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

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

 

· MemberRepository

@Repository
public interface MemberRepository extends JpaRepository<Member, Long> {

    ...

    // 로그인 - DB 기반
    Member findByEmail(String email);
}

 

 

TEST

✅ 접속 화면

 

✅ 아이디 오류 화면

 

✅ 비밀번호 오류 화면

 

✅ 정상 로그인 화면

 

🫧 Postman 으로 확인하기

☑️ Postman 프로그램으로 로그인 시도 시, 스프링 시큐리티 비밀번호 비교가 이루어지지 않아 비교 로직을 추가 구현하여 테스트

 

· LoginDto

@Getter @Setter
@NoArgsConstructor
public class LoginDto {

    private String email;
    private String password;
    private String message;

    @Builder
    public LoginDto(String email, String password) {
        this.email = email;
        this.password = password;
        this.message = null;
    }
}

 

· MemberController

@RestController
@RequiredArgsConstructor
public class MemberController {
    private final MemberService memberService;
    private final CustomUserDetailService customUserDetailService;

    ...

    // 로그인
    @PostMapping("/user/login")
    public String login(@RequestBody LoginDto loginDto) {
        //customUserDetailService.loadUserByUsername(loginDto.getEmail());
        memberService.login(loginDto);
        return loginDto.getMessage();
    }
}

 

· MemberService

@Service
@RequiredArgsConstructor
public class MemberService {

    private final MemberRepository memberRepository;
    private final BCryptPasswordEncoder bCryptPasswordEncoder;

    ...

    // 로그인
    public UserDetails login(LoginDto loginDto) throws UsernameNotFoundException {
        Member savedMember = memberRepository.findByEmail(loginDto.getEmail());

        if (savedMember != null) { // 데이터가 있음
            // 비밀번호 비교하기
            String inputPassword = loginDto.getPassword();
            String savedPassword = savedMember.getPassword();

            if (bCryptPasswordEncoder.matches(inputPassword, savedPassword)) {
                // 비밀번호 일치
                loginDto.setMessage("로그인 성공");
                return new CustomUserDetail(savedMember);
            }
        }
        /* 웹으로 하면 적용되는데 postman 사용 시 비밀번호 비교가 자동으로 안된다
        if (savedMember != null) {
            loginDto.setMessage("로그인 성공");
            return new CustomUserDetail(savedMember);
        }
         */
        
        loginDto.setMessage("로그인 실패");
        return null;
    }
}

 

 

TEST

✅ 로그인 성공

 

✅ 로그인 실패