|
| 1 | +package apptive.devlog.auth; |
| 2 | + |
| 3 | +import apptive.devlog.auth.token.RefreshToken; |
| 4 | +import apptive.devlog.auth.token.RefreshTokenRepository; |
| 5 | +import apptive.devlog.auth.token.TokenProvider; |
| 6 | +import apptive.devlog.exception.EmailAlreadyExistsException; |
| 7 | +import apptive.devlog.exception.InvalidPasswordException; |
| 8 | +import apptive.devlog.exception.NicknameAlreadyExistsException; |
| 9 | +import apptive.devlog.user.User; |
| 10 | +import apptive.devlog.user.UserRepository; |
| 11 | +import org.springframework.security.authentication.AuthenticationManager; |
| 12 | +import org.springframework.security.authentication.BadCredentialsException; |
| 13 | +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; |
| 14 | +import org.springframework.security.crypto.password.PasswordEncoder; |
| 15 | +import org.springframework.stereotype.Service; |
| 16 | +import org.springframework.transaction.annotation.Transactional; |
| 17 | + |
| 18 | +import apptive.devlog.auth.dto.*; |
| 19 | +import lombok.RequiredArgsConstructor; |
| 20 | + |
| 21 | +import java.time.LocalDateTime; |
| 22 | +import java.util.regex.Pattern; |
| 23 | + |
| 24 | +@Service |
| 25 | +@RequiredArgsConstructor |
| 26 | +@Transactional |
| 27 | +public class AuthService { |
| 28 | + private final AuthenticationManager authenticationManager; |
| 29 | + private final TokenProvider tokenProvider; |
| 30 | + private final UserRepository userRepository; |
| 31 | + private final RefreshTokenRepository refreshTokenRepository; |
| 32 | + private final PasswordEncoder passwordEncoder; |
| 33 | + |
| 34 | + public void register(RegisterRequest request) { |
| 35 | + if (userRepository.existsByEmail(request.email())) { |
| 36 | + throw new EmailAlreadyExistsException("이미 사용중인 이메일입니다."); |
| 37 | + } |
| 38 | + if (userRepository.existsByNickname(request.nickname())) { |
| 39 | + throw new NicknameAlreadyExistsException("이미 사용중인 닉네임입니다."); |
| 40 | + } |
| 41 | + if (!validatePassword(request.password())) { |
| 42 | + throw new InvalidPasswordException("비밀번호는 대소문자, 특수문자 포함 10자 이상이어야 합니다."); |
| 43 | + } |
| 44 | + |
| 45 | + User user = User.builder() |
| 46 | + .email(request.email()) |
| 47 | + .password(passwordEncoder.encode(request.password())) |
| 48 | + .name(request.name()) |
| 49 | + .nickname(request.nickname()) |
| 50 | + .birth(request.birth()) |
| 51 | + .gender(request.gender()) |
| 52 | + .build(); |
| 53 | + userRepository.save(user); |
| 54 | + } |
| 55 | + |
| 56 | + public LoginResult login(LoginRequest request) { |
| 57 | + try { |
| 58 | + authenticationManager.authenticate( |
| 59 | + new UsernamePasswordAuthenticationToken(request.email(), request.password())); |
| 60 | + |
| 61 | + User user = userRepository.findByEmail(request.email()) |
| 62 | + .orElseThrow(() -> new BadCredentialsException("사용자 없음")); |
| 63 | + |
| 64 | + String accessTokenString = tokenProvider.generateAccessToken(user.getEmail()); |
| 65 | + String refreshTokenString = tokenProvider.generateRefreshToken(); |
| 66 | + RefreshToken refreshToken = RefreshToken.builder() |
| 67 | + .token(refreshTokenString) |
| 68 | + .userEmail(request.email()) |
| 69 | + .expiry(LocalDateTime.now().plusDays(TokenProvider.REFRESH_TOKEN_TTL)) |
| 70 | + .build(); |
| 71 | + refreshTokenRepository.deleteByUserEmail(request.email()); |
| 72 | + refreshTokenRepository.save(refreshToken); |
| 73 | + |
| 74 | + return new LoginResult(accessTokenString, refreshTokenString); |
| 75 | + } catch (BadCredentialsException exception) { |
| 76 | + throw new BadCredentialsException("이메일 또는 비밀번호가 잘못되었습니다."); |
| 77 | + } |
| 78 | + } |
| 79 | + |
| 80 | + public void logout(String email) { |
| 81 | + refreshTokenRepository.deleteByUserEmail(email); |
| 82 | + } |
| 83 | + |
| 84 | + public String refresh(String refreshTokenString) { |
| 85 | + RefreshToken refreshToken = refreshTokenRepository.findByToken(refreshTokenString); |
| 86 | + if(refreshToken == null || refreshToken.getExpiry().isBefore(LocalDateTime.now())) |
| 87 | + throw new BadCredentialsException("RefreshToken이 바르지 않습니다."); |
| 88 | + |
| 89 | + return tokenProvider.generateAccessToken(refreshToken.getUserEmail()); |
| 90 | + } |
| 91 | + |
| 92 | + private boolean validatePassword(String password) { |
| 93 | + Pattern pattern = Pattern.compile("^(?=.*[A-Z])(?=.*[a-z])(?=.*\\d)(?=.*[^a-zA-Z0-9]).{10,}$"); |
| 94 | + return pattern.matcher(password).matches(); |
| 95 | + } |
| 96 | +} |
0 commit comments