diff --git a/src/main/java/com/gam/api/common/message/ExceptionMessage.java b/src/main/java/com/gam/api/common/message/ExceptionMessage.java index 04b3c39e..8fe753c9 100644 --- a/src/main/java/com/gam/api/common/message/ExceptionMessage.java +++ b/src/main/java/com/gam/api/common/message/ExceptionMessage.java @@ -9,6 +9,7 @@ public enum ExceptionMessage { /** auth **/ EMPTY_TOKEN("빈 토큰입니다."), INVALID_TOKEN("유효하지 않은 토큰입니다."), + INVALID_KAKAO_TOKEN("유효하지 않은 카카오 토큰입니다."), EXPIRED_TOKEN("만료된 토큰입니다."), INVALID_SIGNATURE("유효하지 않은 서명입니다."), PROFILE_UNCOMPLETED_USER("마이페이지를 작성하지 않은 유저입니다."), diff --git a/src/main/java/com/gam/api/dto/kakao/KakaoUserResponse.java b/src/main/java/com/gam/api/dto/kakao/KakaoUserResponse.java index 422d21aa..90bd45c9 100644 --- a/src/main/java/com/gam/api/dto/kakao/KakaoUserResponse.java +++ b/src/main/java/com/gam/api/dto/kakao/KakaoUserResponse.java @@ -4,4 +4,4 @@ import com.fasterxml.jackson.databind.annotation.JsonNaming; @JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class) -public record KakaoUserResponse(String id) {} +public record KakaoUserResponse(String id, String connected_at) {} \ No newline at end of file diff --git a/src/main/java/com/gam/api/service/social/AppleSocialService.java b/src/main/java/com/gam/api/service/social/AppleSocialService.java index 5a3e6be9..5a83108b 100644 --- a/src/main/java/com/gam/api/service/social/AppleSocialService.java +++ b/src/main/java/com/gam/api/service/social/AppleSocialService.java @@ -1,78 +1,28 @@ package com.gam.api.service.social; import com.gam.api.common.exception.AuthException; -import com.gam.api.common.util.RedisUtil; -import com.gam.api.config.GamConfig; -import com.gam.api.config.jwt.JwtTokenManager; import com.gam.api.dto.social.response.SocialLoginResponseDTO; -import com.gam.api.entity.AuthProvider; -import com.gam.api.entity.Role; -import com.gam.api.entity.User; -import com.gam.api.entity.UserStatus; -import com.gam.api.repository.AuthProviderRepository; -import com.gam.api.repository.UserRepository; import com.nimbusds.jwt.SignedJWT; import lombok.RequiredArgsConstructor; import lombok.val; -import org.springframework.data.redis.core.RedisTemplate; import org.springframework.http.HttpStatus; import org.springframework.stereotype.Service; import com.gam.api.dto.social.request.SocialLoginRequestDTO; import javax.transaction.Transactional; import java.text.ParseException; -import java.util.Objects; @Service @RequiredArgsConstructor public class AppleSocialService implements SocialService { - private final AuthProviderRepository authProviderRepository; - private final UserRepository userRepository; - - private final JwtTokenManager jwtTokenManager; - private final GamConfig gamConfig; - - private final RedisTemplate redisTemplate; + private final SocialCommonService socialCommonService; @Override @Transactional public SocialLoginResponseDTO login(SocialLoginRequestDTO request) { val appleUserId = getUserInfo(request.token()); - val parsedAppleUserId = appleUserId; - - val authProvider = authProviderRepository.searchAuthProviderById(parsedAppleUserId); - - if (Objects.nonNull(authProvider)) { - val user = authProvider.getUser(); - val userId = user.getId(); - val accessToken = jwtTokenManager.createAccessToken(userId); - val refreshToken = jwtTokenManager.createRefreshToken(userId); - - RedisUtil.saveRefreshToken(redisTemplate, refreshToken, userId); - - val isProfileCompleted = chkProfileCompleted(user); - return SocialLoginResponseDTO.of(true, isProfileCompleted, userId, accessToken, refreshToken, gamConfig.getAppVersion()); - } - - val user = userRepository.save(User.builder() - .role(Role.USER) - .userStatus(UserStatus.NOT_PERMITTED) - .build()); - - val userId = user.getId(); - val accessToken = jwtTokenManager.createAccessToken(userId); - val refreshToken = jwtTokenManager.createRefreshToken(userId); - - RedisUtil.saveRefreshToken(redisTemplate, refreshToken, userId); - - authProviderRepository.save(AuthProvider.builder() - .id(parsedAppleUserId) - .user(user) - .providerType(request.providerType()) - .build()); - - return SocialLoginResponseDTO.of(false, false, userId, accessToken, refreshToken, gamConfig.getAppVersion()); + return socialCommonService.gamLogin(appleUserId, request.providerType()); } private String getUserInfo (String idToken) { @@ -85,9 +35,4 @@ private String getUserInfo (String idToken) { throw new AuthException("잘못된 토큰입니다.", HttpStatus.BAD_REQUEST); } } - - @Override - public boolean chkProfileCompleted(User user) { - return !Objects.isNull(user.getInfo()) && !Objects.isNull(user.getUserTag()); - } } diff --git a/src/main/java/com/gam/api/service/social/KakaoSocialService.java b/src/main/java/com/gam/api/service/social/KakaoSocialService.java index 7c85e91a..59af8d76 100644 --- a/src/main/java/com/gam/api/service/social/KakaoSocialService.java +++ b/src/main/java/com/gam/api/service/social/KakaoSocialService.java @@ -1,80 +1,34 @@ package com.gam.api.service.social; -import com.gam.api.common.util.RedisUtil; -import com.gam.api.config.GamConfig; -import com.gam.api.config.jwt.JwtTokenManager; +import com.gam.api.common.exception.AuthException; +import com.gam.api.common.message.ExceptionMessage; +import com.gam.api.dto.kakao.KakaoUserResponse; import com.gam.api.dto.social.response.SocialLoginResponseDTO; -import com.gam.api.entity.AuthProvider; -import com.gam.api.entity.Role; -import com.gam.api.entity.User; -import com.gam.api.entity.UserStatus; -import com.gam.api.repository.AuthProviderRepository; -import com.gam.api.repository.UserRepository; +import feign.FeignException; import lombok.RequiredArgsConstructor; -import lombok.val; -import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.http.HttpStatus; import org.springframework.stereotype.Service; import com.gam.api.external.kakao.KakaoApiClient; import com.gam.api.dto.social.request.SocialLoginRequestDTO; import javax.transaction.Transactional; -import java.util.Objects; @Service @RequiredArgsConstructor public class KakaoSocialService implements SocialService { - - private final AuthProviderRepository authProviderRepository; - private final UserRepository userRepository; - private final KakaoApiClient kakaoApiClient; - - private final JwtTokenManager jwtTokenManager; - private final GamConfig gamConfig; - - private final RedisTemplate redisTemplate; + private final SocialCommonService socialCommonService; @Override @Transactional public SocialLoginResponseDTO login(SocialLoginRequestDTO request) { - val userResponse = kakaoApiClient.getUserInformation("Bearer " + request.token()); - - val authProvider = authProviderRepository.searchAuthProviderById(userResponse.id()); - - if(Objects.nonNull(authProvider)) { - val user = authProvider.getUser(); - val userId = user.getId(); - val accessToken = jwtTokenManager.createAccessToken(userId); - val refreshToken = jwtTokenManager.createRefreshToken(userId); - - RedisUtil.saveRefreshToken(redisTemplate, refreshToken, userId); - - val isProfileCompleted = chkProfileCompleted(user); - return SocialLoginResponseDTO.of(true, isProfileCompleted, userId, accessToken, refreshToken, gamConfig.getAppVersion()); + KakaoUserResponse userResponse; + try { + userResponse = kakaoApiClient.getUserInformation("Bearer " + request.token()); + } catch (FeignException feignException) { + throw new AuthException(ExceptionMessage.INVALID_KAKAO_TOKEN.getMessage(), HttpStatus.BAD_REQUEST); } - val user = userRepository.save(User.builder() - .role(Role.USER) - .userStatus(UserStatus.NOT_PERMITTED) - .build()); - - val userId = user.getId(); - val accessToken = jwtTokenManager.createAccessToken(userId); - val refreshToken = jwtTokenManager.createRefreshToken(userId); - - RedisUtil.saveRefreshToken(redisTemplate, refreshToken, userId); - - authProviderRepository.save(AuthProvider.builder() - .id(userResponse.id()) - .user(user) - .providerType(request.providerType()) - .build()); - - return SocialLoginResponseDTO.of(false, false, userId, accessToken, refreshToken, gamConfig.getAppVersion()); - } - - @Override - public boolean chkProfileCompleted(User user) { - return !Objects.isNull(user.getInfo()) && !Objects.isNull(user.getUserTag()); + return socialCommonService.gamLogin(userResponse.id(), request.providerType()); } } diff --git a/src/main/java/com/gam/api/service/social/SocialCommonService.java b/src/main/java/com/gam/api/service/social/SocialCommonService.java index 02cd1c55..2d45306a 100644 --- a/src/main/java/com/gam/api/service/social/SocialCommonService.java +++ b/src/main/java/com/gam/api/service/social/SocialCommonService.java @@ -2,10 +2,14 @@ import com.gam.api.dto.social.request.SocialLogoutRequestDTO; import com.gam.api.dto.social.request.SocialRefreshRequestDTO; +import com.gam.api.dto.social.response.SocialLoginResponseDTO; import com.gam.api.dto.social.response.SocialRefreshResponseDTO; +import com.gam.api.entity.ProviderType; public interface SocialCommonService { void logout(SocialLogoutRequestDTO request); SocialRefreshResponseDTO refresh(SocialRefreshRequestDTO request); + + SocialLoginResponseDTO gamLogin(String thirdPartyUserId, ProviderType providerType); } diff --git a/src/main/java/com/gam/api/service/social/SocialCommonServiceImpl.java b/src/main/java/com/gam/api/service/social/SocialCommonServiceImpl.java index 3be276b9..8e3e555b 100644 --- a/src/main/java/com/gam/api/service/social/SocialCommonServiceImpl.java +++ b/src/main/java/com/gam/api/service/social/SocialCommonServiceImpl.java @@ -3,10 +3,15 @@ import com.gam.api.common.message.ExceptionMessage; import com.gam.api.common.exception.AuthException; import com.gam.api.common.util.RedisUtil; +import com.gam.api.config.GamConfig; import com.gam.api.config.jwt.JwtTokenManager; import com.gam.api.dto.social.request.SocialLogoutRequestDTO; import com.gam.api.dto.social.request.SocialRefreshRequestDTO; +import com.gam.api.dto.social.response.SocialLoginResponseDTO; import com.gam.api.dto.social.response.SocialRefreshResponseDTO; +import com.gam.api.entity.*; +import com.gam.api.repository.AuthProviderRepository; +import com.gam.api.repository.UserRepository; import lombok.RequiredArgsConstructor; import lombok.val; import org.springframework.data.redis.core.RedisTemplate; @@ -20,7 +25,46 @@ @Service public class SocialCommonServiceImpl implements SocialCommonService { private final JwtTokenManager jwtTokenManager; + private final AuthProviderRepository authProviderRepository; + private final UserRepository userRepository; private final RedisTemplate redisTemplate; + private final GamConfig gamConfig; + + private boolean chkProfileCompleted(User user) { + return !Objects.isNull(user.getInfo()) && !Objects.isNull(user.getUserTag()); + } + + private SocialLoginResponseDTO reLogin(User user) { + val userId = user.getId(); + val accessToken = jwtTokenManager.createAccessToken(userId); + val refreshToken = jwtTokenManager.createRefreshToken(userId); + + RedisUtil.saveRefreshToken(redisTemplate, refreshToken, userId); + + val isProfileCompleted = chkProfileCompleted(user); + return SocialLoginResponseDTO.of(true, isProfileCompleted, userId, accessToken, refreshToken, gamConfig.getAppVersion()); + } + + private SocialLoginResponseDTO SignUpAndLogin(String thirdPartyUserId, ProviderType providerType) { + val user = userRepository.save(User.builder() + .role(Role.USER) + .userStatus(UserStatus.NOT_PERMITTED) + .build()); + + val userId = user.getId(); + val accessToken = jwtTokenManager.createAccessToken(userId); + val refreshToken = jwtTokenManager.createRefreshToken(userId); + + RedisUtil.saveRefreshToken(redisTemplate, refreshToken, userId); + + authProviderRepository.save(AuthProvider.builder() + .id(thirdPartyUserId) + .user(user) + .providerType(providerType) + .build()); + + return SocialLoginResponseDTO.of(false, false, userId, accessToken, refreshToken, gamConfig.getAppVersion()); + } @Override @Transactional @@ -78,4 +122,16 @@ public SocialRefreshResponseDTO refresh(SocialRefreshRequestDTO socialRefreshReq return SocialRefreshResponseDTO.of(accessToken, refreshToken); } + + @Override + @Transactional + public SocialLoginResponseDTO gamLogin(String thirdPartyUserId, ProviderType providerType) { + val authProvider = authProviderRepository.searchAuthProviderById(thirdPartyUserId); + + if (Objects.nonNull(authProvider)) { + return reLogin(authProvider.getUser()); + } + + return SignUpAndLogin(thirdPartyUserId, providerType); + } } diff --git a/src/main/java/com/gam/api/service/social/SocialService.java b/src/main/java/com/gam/api/service/social/SocialService.java index 7bdf340f..8d00aa09 100644 --- a/src/main/java/com/gam/api/service/social/SocialService.java +++ b/src/main/java/com/gam/api/service/social/SocialService.java @@ -2,9 +2,7 @@ import com.gam.api.dto.social.request.SocialLoginRequestDTO; import com.gam.api.dto.social.response.SocialLoginResponseDTO; -import com.gam.api.entity.User; public interface SocialService { SocialLoginResponseDTO login(SocialLoginRequestDTO request); - boolean chkProfileCompleted(User user); }