From 128338118bf632a83a39b385fc391a065e830692 Mon Sep 17 00:00:00 2001 From: Hyoseop Song Date: Mon, 30 Sep 2024 05:30:31 +0900 Subject: [PATCH] =?UTF-8?q?:recycle:=20refactor:=20=EC=82=AC=EC=9A=A9?= =?UTF-8?q?=EC=9E=90=20=EC=A4=91=EB=B3=B5=20OAuth=20=EB=A1=9C=EA=B7=B8?= =?UTF-8?q?=EC=9D=B8=20=EA=B2=80=EC=A6=9D=20=EB=A1=9C=EC=A7=81=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80=20(#52)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../social/strategy/KakaoAuthStrategy.java | 101 ++++++++++-------- .../toyouserver/domain/UserSocialAccount.java | 36 +++++++ .../UserSocialAccountRepository.java | 9 ++ 3 files changed, 104 insertions(+), 42 deletions(-) create mode 100644 src/main/java/slvtwn/khu/toyouserver/domain/UserSocialAccount.java create mode 100644 src/main/java/slvtwn/khu/toyouserver/persistance/UserSocialAccountRepository.java diff --git a/src/main/java/slvtwn/khu/toyouserver/common/authentication/social/strategy/KakaoAuthStrategy.java b/src/main/java/slvtwn/khu/toyouserver/common/authentication/social/strategy/KakaoAuthStrategy.java index 48d521a..c3fc0f5 100644 --- a/src/main/java/slvtwn/khu/toyouserver/common/authentication/social/strategy/KakaoAuthStrategy.java +++ b/src/main/java/slvtwn/khu/toyouserver/common/authentication/social/strategy/KakaoAuthStrategy.java @@ -2,6 +2,7 @@ import static slvtwn.khu.toyouserver.domain.SocialAuthProvider.KAKAO; +import java.util.Optional; import lombok.RequiredArgsConstructor; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; @@ -13,59 +14,75 @@ import slvtwn.khu.toyouserver.common.feign.auth.kakao.web.KakaoTokenResponse; import slvtwn.khu.toyouserver.common.feign.auth.kakao.web.KakaoUserResponse; import slvtwn.khu.toyouserver.domain.User; +import slvtwn.khu.toyouserver.domain.UserSocialAccount; import slvtwn.khu.toyouserver.dto.SocialAuthRequest; import slvtwn.khu.toyouserver.dto.SocialAuthResponse; -import slvtwn.khu.toyouserver.persistance.EventRepository; import slvtwn.khu.toyouserver.persistance.UserRepository; +import slvtwn.khu.toyouserver.persistance.UserSocialAccountRepository; @Service @RequiredArgsConstructor public class KakaoAuthStrategy implements SocialAuthStrategy { - @Value("${oauth.kakao.client-id}") - private String kakaoClientId; - @Value("${oauth.kakao.redirect-uri}") - private String kakaoRedirectUri; - @Value("${oauth.kakao.grant-type}") - private String kakaoGrantType; + private final UserSocialAccountRepository userSocialAccountRepository; + @Value("${oauth.kakao.client-id}") + private String kakaoClientId; + @Value("${oauth.kakao.redirect-uri}") + private String kakaoRedirectUri; + @Value("${oauth.kakao.grant-type}") + private String kakaoGrantType; - private final KakaoAuthApiClient kakaoAuthApiClient; - private final KakaoResourceApiClient kakaoResourceApiClient; + private final KakaoAuthApiClient kakaoAuthApiClient; + private final KakaoResourceApiClient kakaoResourceApiClient; - private final UserRepository userRepository; + private final UserRepository userRepository; - private final JwtProvider jwtProvider; + private final JwtProvider jwtProvider; - // TODO: 파사드로 카카오 요청 + 유저 저장 부분 분리 - // 현재 외부 네트워크에 트랜잭션이 의존하는 상태 - @Override - @Transactional - public SocialAuthResponse login(SocialAuthRequest request) { - KakaoTokenResponse tokenResponse = kakaoAuthApiClient.getOAuth2AccessToken( - kakaoGrantType, - kakaoClientId, - kakaoRedirectUri, - request.authorizationCode() - ); - KakaoUserResponse userResponse = kakaoResourceApiClient.getUserInformation( - "Bearer " + tokenResponse.accessToken()); - User user = registerUser(userResponse); - Token token = jwtProvider.issueTokens(user.getId()); - return SocialAuthResponse.of(user.getId(), user.getName(), KAKAO, token); - } + // TODO: 파사드로 카카오 요청 + 유저 저장 부분 분리 + // 현재 외부 네트워크에 트랜잭션이 의존하는 상태 + @Override + @Transactional + public SocialAuthResponse login(SocialAuthRequest request) { + KakaoTokenResponse tokenResponse = kakaoAuthApiClient.getOAuth2AccessToken( + kakaoGrantType, + kakaoClientId, + kakaoRedirectUri, + request.authorizationCode() + ); + KakaoUserResponse userResponse = kakaoResourceApiClient.getUserInformation( + "Bearer " + tokenResponse.accessToken()); + User user = findOrCreateUser(userResponse); + Token token = jwtProvider.issueTokens(user.getId()); + return SocialAuthResponse.of(user.getId(), user.getName(), KAKAO, token); + } - @Override - public boolean support(String provider) { - return provider.equals("KAKAO"); - } + @Override + public boolean support(String provider) { + return provider.equals("KAKAO"); + } - private User registerUser(KakaoUserResponse userResponse) { - User user = userRepository.findById(Long.parseLong(userResponse.id())).orElse(null); - if (user == null) { - user = User.create(userResponse.kakaoAccount().profile().nickname(), - userResponse.kakaoAccount().profile().profileImageUrl(), KAKAO); - } - userRepository.save(user); - return user; - } -} + private User findOrCreateUser(KakaoUserResponse userResponse) { + Optional account = userSocialAccountRepository.findByProviderSerial( + userResponse.id()); + if (account.isPresent()) { + UserSocialAccount verifiedSocialAccount = account.get(); + return userRepository.findById(verifiedSocialAccount.getUserId()).orElseThrow( + () -> new IllegalStateException("등록된 카카오 계정에 해당하는 유저가 없습니다.")); + } else { + return registerUser(userResponse); + } + } + + private User registerUser(KakaoUserResponse userResponse) { + User user = User.create( + userResponse.kakaoAccount().profile().nickname(), + userResponse.kakaoAccount().profile().profileImageUrl(), + KAKAO + ); + userRepository.save(user); + UserSocialAccount newAccount = UserSocialAccount.createAccountByKakao(user.getId(), userResponse.id()); + userSocialAccountRepository.save(newAccount); + return user; + } +} \ No newline at end of file diff --git a/src/main/java/slvtwn/khu/toyouserver/domain/UserSocialAccount.java b/src/main/java/slvtwn/khu/toyouserver/domain/UserSocialAccount.java new file mode 100644 index 0000000..66e94b3 --- /dev/null +++ b/src/main/java/slvtwn/khu/toyouserver/domain/UserSocialAccount.java @@ -0,0 +1,36 @@ +package slvtwn.khu.toyouserver.domain; + + +import static jakarta.persistence.GenerationType.IDENTITY; + +import jakarta.persistence.Entity; +import jakarta.persistence.EnumType; +import jakarta.persistence.Enumerated; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.Id; +import jakarta.persistence.Table; +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Entity +@Table(name = "user_social_accounts") +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@AllArgsConstructor(access = AccessLevel.PRIVATE) +@Getter +public class UserSocialAccount { + + @Id + @GeneratedValue(strategy = IDENTITY) + private Long id; + + @Enumerated(EnumType.STRING) + private SocialAuthProvider provider; + private String providerSerial; + private Long userId; + + public static UserSocialAccount createAccountByKakao(Long userId, String providerSerial) { + return new UserSocialAccount(null, SocialAuthProvider.KAKAO, providerSerial, userId); + } +} diff --git a/src/main/java/slvtwn/khu/toyouserver/persistance/UserSocialAccountRepository.java b/src/main/java/slvtwn/khu/toyouserver/persistance/UserSocialAccountRepository.java new file mode 100644 index 0000000..a5c419b --- /dev/null +++ b/src/main/java/slvtwn/khu/toyouserver/persistance/UserSocialAccountRepository.java @@ -0,0 +1,9 @@ +package slvtwn.khu.toyouserver.persistance; + +import java.util.Optional; +import org.springframework.data.jpa.repository.JpaRepository; +import slvtwn.khu.toyouserver.domain.UserSocialAccount; + +public interface UserSocialAccountRepository extends JpaRepository { + Optional findByProviderSerial(String providerSerial); +}