Skip to content

Commit

Permalink
[refac] 소셜로그인 코드 리펙토링 (#24)
Browse files Browse the repository at this point in the history
* [refac] apply code review

* [refac] apply code review

* [refac] apply code review
  • Loading branch information
kgy1008 authored Jul 8, 2024
1 parent cbcb625 commit 6ac56eb
Show file tree
Hide file tree
Showing 18 changed files with 191 additions and 119 deletions.
2 changes: 1 addition & 1 deletion server-yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,8 @@

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;

@SpringBootApplication
@EnableFeignClients
public class HankkiserverApplication {

public static void main(String[] args) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

@RestController
@RequiredArgsConstructor
@RequestMapping("api/v1")
@RequestMapping("/api/v1")
public class AuthController {

private final AuthService authService;
Expand Down Expand Up @@ -46,8 +46,8 @@ public ResponseEntity<BaseResponse<?>> withdraw(

@PostMapping("/auth/reissue")
public ResponseEntity<BaseResponse<?>> reissue(
@RequestHeader(HttpHeaders.AUTHORIZATION) final String refreshtoken) {
final UserReissueResponse response = authService.reissue(refreshtoken);
@RequestHeader(HttpHeaders.AUTHORIZATION) final String refreshToken) {
final UserReissueResponse response = authService.reissue(refreshToken);
return ApiResponse.success(SuccessCode.OK, response);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,34 +8,35 @@
import org.hankki.hankkiserver.domain.user.model.User;
import org.hankki.hankkiserver.domain.user.model.UserInfo;
import org.hankki.hankkiserver.domain.user.model.Platform;
import org.hankki.hankkiserver.common.exception.EntityNotFoundException;
import org.hankki.hankkiserver.common.exception.InvalidValueException;
import org.hankki.hankkiserver.common.exception.UnauthorizedException;
import org.hankki.hankkiserver.external.openfeign.apple.AppleOAuthProvider;
import org.hankki.hankkiserver.external.openfeign.dto.SocialInfoDto;
import org.hankki.hankkiserver.domain.user.repository.UserInfoRepository;
import org.hankki.hankkiserver.domain.user.repository.UserRepository;
import org.hankki.hankkiserver.api.auth.controller.request.UserLoginRequest;
import org.hankki.hankkiserver.api.auth.service.response.UserLoginResponse;
import org.hankki.hankkiserver.api.auth.service.response.UserReissueResponse;
import org.hankki.hankkiserver.external.openfeign.kakao.KakaoOAuthProvider;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Optional;

import static org.hankki.hankkiserver.domain.user.model.MemberStatus.ACTIVE;
import static org.hankki.hankkiserver.domain.user.model.MemberStatus.INACTIVE;
import static org.hankki.hankkiserver.domain.user.model.Platform.*;
import static org.hankki.hankkiserver.domain.user.model.User.createUser;
import static org.hankki.hankkiserver.domain.user.model.UserInfo.createMemberInfo;
import static org.hankki.hankkiserver.domain.user.model.Platform.APPLE;
import static org.hankki.hankkiserver.domain.user.model.Platform.KAKAO;
import static org.hankki.hankkiserver.auth.filter.JwtAuthenticationFilter.BEARER;
import static org.hankki.hankkiserver.domain.user.model.User.createUser;

@Service
@Transactional
@RequiredArgsConstructor
public class AuthService {

private final UserRepository userRepository;
private final UserInfoRepository userInfoRepository;
private final UserFinder userFinder;
private final UserSaver userSaver;
private final UserInfoFinder userInfoFinder;
private final UserInfoSaver userInfoSaver;
private final UserInfoDeleter userInfoDeleter;
private final JwtProvider jwtProvider;
private final JwtValidator jwtValidator;
private final KakaoOAuthProvider kakaoOAuthProvider;
Expand All @@ -44,50 +45,48 @@ public class AuthService {
public UserLoginResponse login(
final String token,
final UserLoginRequest request) {
Platform platform = getEnumPlatformFromStringPlatform(request.platform());
Platform platform = Platform.getEnumPlatformFromStringPlatform(request.platform());
SocialInfoDto socialInfo = getSocialInfo(token, platform, request.name());
boolean isRegistered = isRegisteredUser(platform, socialInfo);
User findUser = loadOrCreateUser(platform, socialInfo, isRegistered);
boolean isRegistered = userFinder.isRegisteredUser(platform, socialInfo);
User findUser = loadOrCreateUser(platform, socialInfo);
Token issuedToken = generateTokens(findUser.getId());
return UserLoginResponse.of(issuedToken, isRegistered);
}

public void logOut(final Long userId) {
UserInfo findUserInfo = getUserInfo(userId);
updateRefreshToken(null, findUserInfo);
public void logOut(final long userId) {
UserInfo findUserInfo = userInfoFinder.getUserInfo(userId);
findUserInfo.updateRefreshToken(null);
}

public void withdraw(final Long userId, final String code) {
User user = getUser(userId);
if (user.getPlatform() == APPLE){
public void withdraw(final long userId, final String code) {
User user = userFinder.getUser(userId);
if (APPLE == user.getPlatform()){
try {
String refreshToken = appleOAuthProvider.getAppleToken(code);
appleOAuthProvider.requestRevoke(refreshToken);
} catch (Exception e) {
throw new InvalidValueException(ErrorCode.APPLE_REVOKE_FAILED);
}
}

userRepository.softDeleteById(userId, INACTIVE);
userInfoRepository.softDeleteByUserId(userId);
user.softDelete(INACTIVE);
user.softDelete();
userInfoDeleter.softDelete(userId);
}

@Transactional(noRollbackFor = UnauthorizedException.class)
public UserReissueResponse reissue(final String refreshToken) {
Long userId = jwtProvider.getSubject(refreshToken.substring(BEARER.length()));
long userId = jwtProvider.getSubject(refreshToken.substring(BEARER.length()));
validateRefreshToken(refreshToken, userId);
UserInfo findUserInfo = getUserInfo(userId);
Token issueToken = jwtProvider.issueToken(userId);
updateRefreshToken(issueToken.refreshToken(), findUserInfo);
return UserReissueResponse.of(issueToken);
UserInfo findUserInfo = userInfoFinder.getUserInfo(userId);
Token issuedTokens = jwtProvider.issueTokens(userId);
findUserInfo.updateRefreshToken(issuedTokens.refreshToken());
return UserReissueResponse.of(issuedTokens);
}

private Token generateTokens(final Long userId) {
Token issuedToken = jwtProvider.issueToken(userId);
UserInfo findUserInfo = getUserInfo(userId);
updateRefreshToken(issuedToken.refreshToken(), findUserInfo);
return issuedToken;
private Token generateTokens(final long userId) {
Token issuedTokens = jwtProvider.issueTokens(userId);
UserInfo findUserInfo = userInfoFinder.getUserInfo(userId);
findUserInfo.updateRefreshToken(issuedTokens.refreshToken());
return issuedTokens;
}

private SocialInfoDto getSocialInfo(
Expand All @@ -96,76 +95,43 @@ private SocialInfoDto getSocialInfo(
final String name) {
if (KAKAO == platform){
return kakaoOAuthProvider.getKakaoUserInfo(providerToken);
} else if (APPLE == platform){
return appleOAuthProvider.getAppleUserInfo(providerToken, name);
}
throw new EntityNotFoundException(ErrorCode.INVALID_PLATFORM_TYPE);
return appleOAuthProvider.getAppleUserInfo(providerToken, name);
}

private boolean isRegisteredUser(Platform platform, SocialInfoDto socialInfo){
return userRepository.existsByPlatformAndSerialIdAndMemberStatus(
platform,
socialInfo.serialId(),
ACTIVE);
private User loadOrCreateUser(final Platform platform, final SocialInfoDto socialInfo) {
return userFinder.findUserByPlatFormAndSeralId(platform, socialInfo.serialId())
.map(this::updateUserInfo)
.orElseGet(() -> {
User newUser = createUser(
socialInfo.name(),
socialInfo.email(),
socialInfo.serialId(),
platform);
saveUserAndUserInfo(newUser);
return newUser;
});
}

private User loadOrCreateUser(Platform platform, SocialInfoDto socialInfo, boolean isRegistered){
if (!isRegistered){
User newUser = createUser(
socialInfo.name(),
socialInfo.email(),
socialInfo.serialId(),
platform);
saveUser(newUser);
return newUser;
}

User findUser = getUser(platform, socialInfo.serialId());
if (INACTIVE == findUser.getMemberStatus()) {
findUser.softDelete(ACTIVE);
userRepository.save(findUser);
}
return findUser;
}

private User getUser(
final Platform platform,
final String serialId) {
return userRepository.findByPlatformAndSerialId(platform, serialId)
.orElseThrow(() -> new EntityNotFoundException(ErrorCode.USER_NOT_FOUND));
}

private User getUser(final Long userId) {
return userRepository.findById(userId)
.orElseThrow(() -> new EntityNotFoundException(ErrorCode.USER_NOT_FOUND));
}

private UserInfo getUserInfo(final Long memberId) {
return userInfoRepository.findByUserId(memberId)
.orElseThrow(() -> new EntityNotFoundException(ErrorCode.USER_INFO_NOT_FOUND));
private User updateUserInfo(final User user) {
user.updateStatus(ACTIVE);
userInfoFinder.getUserInfo(user.getId()).updateNickname(user.getName());
return user;
}

private String getRefreshToken(final Long userId) {
return userInfoRepository.findByUserId(userId)
.orElseThrow(() -> new EntityNotFoundException(ErrorCode.REFRESH_TOKEN_NOT_FOUND))
return userInfoFinder.getUserInfo(userId)
.getRefreshToken();
}

private void saveUser(final User user) {
userRepository.save(user);
UserInfo userInfo = createMemberInfo(user, null);
userInfoRepository.save(userInfo);
}

private void updateRefreshToken(
final String refreshToken,
final UserInfo userInfo) {
userInfo.updateRefreshToken(refreshToken);
private void saveUserAndUserInfo(final User user) {
userSaver.saveUser(user);
UserInfo userInfo = UserInfo.createMemberInfo(user, null);
userInfoSaver.saveUserInfo(userInfo);
}

private void validateRefreshToken(
final String refreshToken,
final Long userId) {
private void validateRefreshToken(final String refreshToken, final long userId) {
try {
jwtValidator.validateRefreshToken(refreshToken);
String storedRefreshToken = getRefreshToken(userId);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package org.hankki.hankkiserver.api.auth.service;

import lombok.RequiredArgsConstructor;
import org.hankki.hankkiserver.common.code.ErrorCode;
import org.hankki.hankkiserver.common.exception.EntityNotFoundException;
import org.hankki.hankkiserver.domain.user.model.Platform;
import org.hankki.hankkiserver.domain.user.model.User;
import org.hankki.hankkiserver.domain.user.repository.UserRepository;
import org.hankki.hankkiserver.external.openfeign.dto.SocialInfoDto;
import org.springframework.stereotype.Component;

import java.util.Optional;

import static org.hankki.hankkiserver.domain.user.model.MemberStatus.ACTIVE;

@Component
@RequiredArgsConstructor
public class UserFinder {

private final UserRepository userRepository;

public User getUser(final long userId) {
return userRepository.findById(userId)
.orElseThrow(() -> new EntityNotFoundException(ErrorCode.USER_NOT_FOUND));
}

public boolean isRegisteredUser(final Platform platform, final SocialInfoDto socialInfo) {
return userRepository.existsByPlatformAndSerialIdAndMemberStatus(
platform,
socialInfo.serialId(),
ACTIVE);
}

public Optional<User> findUserByPlatFormAndSeralId(final Platform platform, final String serialId) {
return userRepository.findByPlatformAndSerialId(platform, serialId);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package org.hankki.hankkiserver.api.auth.service;

import lombok.RequiredArgsConstructor;
import org.hankki.hankkiserver.domain.user.repository.UserInfoRepository;
import org.springframework.stereotype.Component;

@Component
@RequiredArgsConstructor
public class UserInfoDeleter {

private final UserInfoRepository userInfoRepository;

public void softDelete(final long userId) {
userInfoRepository.softDeleteByUserId(userId);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package org.hankki.hankkiserver.api.auth.service;

import lombok.RequiredArgsConstructor;
import org.hankki.hankkiserver.common.code.ErrorCode;
import org.hankki.hankkiserver.common.exception.EntityNotFoundException;
import org.hankki.hankkiserver.domain.user.model.UserInfo;
import org.hankki.hankkiserver.domain.user.repository.UserInfoRepository;
import org.springframework.stereotype.Component;

@Component
@RequiredArgsConstructor
public class UserInfoFinder {

private final UserInfoRepository userInfoRepository;

public UserInfo getUserInfo(final long userId) {
return userInfoRepository.findByUserId(userId)
.orElseThrow(() -> new EntityNotFoundException(ErrorCode.USER_INFO_NOT_FOUND));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package org.hankki.hankkiserver.api.auth.service;

import lombok.RequiredArgsConstructor;
import org.hankki.hankkiserver.domain.user.model.UserInfo;
import org.hankki.hankkiserver.domain.user.repository.UserInfoRepository;
import org.springframework.stereotype.Component;

@Component
@RequiredArgsConstructor
public class UserInfoSaver {

private final UserInfoRepository userInfoRepository;

public void saveUserInfo(final UserInfo userInfo) {
userInfoRepository.save(userInfo);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package org.hankki.hankkiserver.api.auth.service;

import lombok.RequiredArgsConstructor;
import org.hankki.hankkiserver.domain.user.model.User;
import org.hankki.hankkiserver.domain.user.repository.UserRepository;
import org.springframework.stereotype.Component;

@Component
@RequiredArgsConstructor
public class UserSaver {

private final UserRepository userRepository;

public void saveUser(final User user) {
userRepository.save(user);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public class UserIdArgumentResolver implements HandlerMethodArgumentResolver {
@Override
public boolean supportsParameter(MethodParameter parameter) {
boolean hasUserIdAnnotation = parameter.hasParameterAnnotation(UserId.class);
boolean isLongType = Long.class.isAssignableFrom(parameter.getParameterType());
boolean isLongType = parameter.getParameterType().equals(Long.class);
return hasUserIdAnnotation && isLongType;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ public class JwtProvider {

private final JwtGenerator jwtGenerator;

public Token issueToken(Long userId) {
public Token issueTokens(Long userId) {
return Token.of(jwtGenerator.generateToken(userId, true),
jwtGenerator.generateToken(userId, false));
}
Expand Down
Loading

0 comments on commit 6ac56eb

Please sign in to comment.