항해 실전 프로젝트 Day 12 - 백오피스 로그인 구현 및 에러수정

박서윤·2023년 12월 12일

AuthController.java

@RestController
@RequiredArgsConstructor
@RequestMapping("/api/auth")
public class AuthController {
    private final JwtUtil jwtUtil;
    private final AuthService authService;

    @PostMapping("/admin/login")
    public ResponseEntity<Void> adminLogin(@RequestBody LoginRequestDto requestDto) {
        // 관리자 인증 서비스로 로그인 처리
        Authentication authentication = authService.authenticateAdmin(requestDto);
        // JWT 토큰 생성
        String token = jwtUtil.createToken(authentication.getName(), UserRole.ADMIN);
        // 토큰을 응답 헤더에 추가
        HttpHeaders headers = new HttpHeaders();
        headers.add(JwtUtil.AUTHORIZATION_HEADER, token);
        // 성공 메시지와 함께 응답 반환
        return ResponseEntity.status(HttpStatus.OK).headers(headers).build();
    }
}

AuthService.java

@Service
@RequiredArgsConstructor
public class AuthService {
    private final AuthenticationManager authenticationManager;

    public Authentication authenticateAdmin(LoginRequestDto requestDto) {
        // 이메일과 비밀번호를 사용하여 UsernamePasswordAuthenticationToken 생성
        UsernamePasswordAuthenticationToken authenticationToken =
                new UsernamePasswordAuthenticationToken(requestDto.email(), requestDto.password());
        // AuthenticationManager를 사용하여 인증 시도 후 인증 성공 시, Authentication 객체 반환
        return authenticationManager.authenticate(authenticationToken);
    }
}

AdminRepository.java

public interface AdminRepository extends JpaRepository<Admin, Long> {
    Optional<Admin> findByEmail(String email);
}

유저가 멤버인지 어드민인지 판단해줘야했기에 로직의 수정이있었다.
UserDetailsImpl.java

@Getter
@AllArgsConstructor
public class UserDetailsImpl implements UserDetails {

    private final Object user;

    @Override
    public String getPassword() {
        if (user instanceof Member) {
            return ((Member) user).getPassword();
        } else if (user instanceof Admin) {
            return ((Admin) user).getPassword();
        }
        throw new CustomException(ErrorCode.UNSUPPORTED_USER_TYPE);
    }

    @Override
    public String getUsername() {
        if (user instanceof Member) {
            return ((Member) user).getEmail();
        } else if (user instanceof Admin) {
            return ((Admin) user).getEmail();
        }
        throw new CustomException(ErrorCode.UNSUPPORTED_USER_TYPE);
    }

    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        if (user instanceof Member) {
            String authority = ((Member) user).getRole().getAuthority();
            return Collections.singletonList(new SimpleGrantedAuthority(authority));
        } else if (user instanceof Admin) {
            String authority = ((Admin) user).getRole().getAuthority();
            return Collections.singletonList(new SimpleGrantedAuthority(authority));
        }
        throw new CustomException(ErrorCode.UNSUPPORTED_USER_TYPE);
    }

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

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

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

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

}
@Service
@RequiredArgsConstructor
public class UserDetailsServiceImpl implements UserDetailsService {

    private final MemberRepository memberRepository;
    private final AdminRepository adminRepository;

    @Override
    public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException {
        // 먼저 관리자 Repository에서 이메일로 관리자 정보 조회 시도
        Optional<Admin> admin = adminRepository.findByEmail(email);
        if (admin.isPresent()) {
            // 관리자 정보가 존재하는 경우 UserDetailsImpl 객체 생성하여 반환
            return new UserDetailsImpl(admin.get());
        } else {
            // 관리자 정보가 없다면, 일반 사용자 Repository에서 조회
            Member member = memberRepository.findByEmail(email)
                    .orElseThrow(() -> new CustomException(ErrorCode.INVALID_EMAIL_PASSWORD));
            // 일반 사용자 정보로 UserDetailsImpl 객체 생성하여 반환
            return new UserDetailsImpl(member);
        }
    }
}

0개의 댓글