Skip to content

Commit

Permalink
feat: 애플 회원가입 / 로그인 구현 및 RestClient 도입 (#277)
Browse files Browse the repository at this point in the history
* feat: 애플 로그인 / 회원가입 구현

* refactor: 불필요 코드 제거 및 정리

* refactor: 불필요 코드 제거 및 정리
  • Loading branch information
sejineer authored Mar 1, 2024
1 parent 8e9af59 commit 08f85fd
Show file tree
Hide file tree
Showing 43 changed files with 377 additions and 366 deletions.
11 changes: 5 additions & 6 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -19,27 +19,27 @@ dependencies {
implementation 'org.springframework.boot:spring-boot-starter-oauth2-client'
implementation 'org.springframework.boot:spring-boot-starter-web'

//Swagger, RestDocs
//Swagger
implementation group: 'org.springdoc', name: 'springdoc-openapi-starter-webmvc-ui', version: '2.1.0'
testImplementation group: 'org.springdoc', name: 'springdoc-openapi-starter-webmvc-api', version: '2.1.0'

//외부 API 호출할 때 쓰는 RestTemplate 라이브러리
implementation group: 'org.apache.httpcomponents.client5', name: 'httpclient5', version: '5.2.1'
implementation 'org.springframework.cloud:spring-cloud-starter-openfeign:4.1.0'

//S3
implementation 'org.springframework.cloud:spring-cloud-starter-aws:2.2.6.RELEASE'

//jwt
implementation group: 'io.jsonwebtoken', name: 'jjwt-api', version: '0.11.5'
runtimeOnly group: 'io.jsonwebtoken', name: 'jjwt-impl', version: '0.11.5'
runtimeOnly group: 'io.jsonwebtoken', name: 'jjwt-jackson', version: '0.11.5'
implementation 'org.bouncycastle:bcpkix-jdk18on:1.77'

//lombok
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
annotationProcessor "org.springframework.boot:spring-boot-configuration-processor"

// http client
implementation 'org.apache.httpcomponents.client5:httpclient5:5.3.1'

//db
implementation group: 'mysql', name: 'mysql-connector-java', version: '8.0.32'
runtimeOnly 'mysql:mysql-connector-java'
Expand All @@ -60,7 +60,6 @@ dependencies {
//Monitoring
implementation 'org.springframework.boot:spring-boot-starter-actuator'
implementation 'io.micrometer:micrometer-registry-prometheus'

}

tasks.named('test') {
Expand Down
168 changes: 71 additions & 97 deletions src/main/java/com/shallwe/domain/auth/application/AuthService.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@

import java.util.Optional;

import com.shallwe.domain.auth.domain.AppleToken;
import com.shallwe.domain.auth.domain.repository.AppleTokenRepository;
import com.shallwe.domain.auth.dto.*;
import com.shallwe.domain.auth.exception.AlreadyExistEmailException;
import com.shallwe.domain.auth.exception.InvalidPasswordException;
import com.shallwe.domain.auth.exception.InvalidProviderIdException;
import com.shallwe.domain.auth.exception.UnRegisteredUserException;
import com.shallwe.domain.auth.dto.request.*;
import com.shallwe.domain.auth.dto.response.AuthRes;
import com.shallwe.domain.auth.exception.*;
import com.shallwe.domain.common.Status;
import com.shallwe.domain.shopowner.domain.ShopOwner;
import com.shallwe.domain.shopowner.domain.repository.ShopOwnerRepository;
import com.shallwe.domain.auth.dto.ShopOwnerChangePasswordReq;
import com.shallwe.domain.shopowner.exception.AlreadyExistPhoneNumberException;
import com.shallwe.domain.shopowner.exception.InvalidPhoneNumberException;
import com.shallwe.domain.shopowner.exception.InvalidShopOwnerException;
Expand All @@ -23,7 +23,6 @@
import com.shallwe.domain.user.domain.User;
import com.shallwe.global.config.security.token.UserPrincipal;
import com.shallwe.global.error.DefaultAuthenticationException;
import com.shallwe.global.infrastructure.feign.apple.AppleClient;
import com.shallwe.global.payload.ErrorCode;
import com.shallwe.global.payload.Message;
import com.shallwe.domain.auth.domain.repository.TokenRepository;
Expand All @@ -32,16 +31,13 @@
import com.shallwe.global.utils.AppleJwtUtils;
import io.jsonwebtoken.Claims;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import lombok.RequiredArgsConstructor;
import org.springframework.web.client.RestTemplate;


@Service
Expand All @@ -57,6 +53,7 @@ public class AuthService {
private final TokenRepository tokenRepository;
private final UserRepository userRepository;
private final ShopOwnerRepository shopOwnerRepository;
private final AppleTokenRepository appleTokenRepository;

@Transactional
public AuthRes signUp(final SignUpReq signUpReq) {
Expand All @@ -66,33 +63,41 @@ public AuthRes signUp(final SignUpReq signUpReq) {
User newUser = User.builder()
.providerId(signUpReq.getProviderId())
.provider(signUpReq.getProvider())
.name(signUpReq.getNickname())
.email(signUpReq.getEmail())
.profileImgUrl(signUpReq.getProfileImgUrl())
.password(passwordEncoder.encode(signUpReq.getProviderId()))
.role(Role.USER)
.build();

userRepository.save(newUser);

UserPrincipal userPrincipal = UserPrincipal.createUser(newUser);
Authentication authentication = new UsernamePasswordAuthenticationToken(
userPrincipal,
null,
userPrincipal.getAuthorities()
);
return getUserAuthRes(newUser);
}

TokenMapping tokenMapping = customTokenProviderService.createToken(authentication);
Token token = Token.builder()
.refreshToken(tokenMapping.getRefreshToken())
.userEmail(tokenMapping.getUserEmail())
@Transactional
public AuthRes appleSignUp(AppleSignUpReq appleSignUpReq) {
Claims claims = appleJwtUtils.getClaimsBy(appleSignUpReq.getIdentityToken());
String providerId = claims.get("sub").toString();

if (userRepository.existsByProviderId(providerId)) {
throw new AlreadyExistsProviderIdException();
}

String appleRefreshToken = appleJwtUtils.getAppleToken(appleSignUpReq.getAuthorizationCode());
AppleToken appleTokenReq = AppleToken.builder()
.providerId(providerId)
.refreshToken(appleRefreshToken)
.build();
tokenRepository.save(token);
appleTokenRepository.save(appleTokenReq);

return AuthRes.builder()
.accessToken(tokenMapping.getAccessToken())
.refreshToken(tokenMapping.getRefreshToken())
User newUser = User.builder()
.providerId(providerId)
.provider(Provider.APPLE)
.email(appleSignUpReq.getEmail())
.password(passwordEncoder.encode(providerId))
.role(Role.USER)
.build();
userRepository.save(newUser);

return getUserAuthRes(newUser);
}

@Transactional
Expand All @@ -103,25 +108,20 @@ public AuthRes signIn(final SignInReq signInReq) {
throw new InvalidPasswordException();
}

UserPrincipal userPrincipal = UserPrincipal.createUser(user);
Authentication authentication = new UsernamePasswordAuthenticationToken(
userPrincipal,
null,
userPrincipal.getAuthorities()
);
return getUserAuthRes(user);
}

TokenMapping tokenMapping = customTokenProviderService.createToken(authentication);
Token token = Token.builder()
.refreshToken(tokenMapping.getRefreshToken())
.userEmail(tokenMapping.getUserEmail())
.build();
@Transactional
public AuthRes appleSignIn(AppleSignInReq appleSignInReq) {
Claims claims = appleJwtUtils.getClaimsBy(appleSignInReq.getIdentityToken());
String providerId = claims.get("sub").toString();

tokenRepository.save(token);
User user = userRepository.findByProviderId(providerId).orElseThrow(InvalidProviderIdException::new);
if (user.getName() == null || user.getPhoneNumber() == null || user.getAge() == null || user.getGender() == null) {
throw new UnRegisteredUserException();
}

return AuthRes.builder()
.accessToken(tokenMapping.getAccessToken())
.refreshToken(token.getRefreshToken())
.build();
return getUserAuthRes(user);
}

@Transactional
Expand All @@ -148,9 +148,10 @@ public AuthRes refresh(final RefreshTokenReq tokenRefreshRequest) {
Token updateToken = token.updateRefreshToken(tokenMapping.getRefreshToken());
tokenRepository.save(updateToken);

AuthRes authResponse = AuthRes.builder().accessToken(tokenMapping.getAccessToken()).refreshToken(updateToken.getRefreshToken()).build();

return authResponse;
return AuthRes.builder().
accessToken(tokenMapping.getAccessToken())
.refreshToken(updateToken.getRefreshToken())
.build();
}

@Transactional
Expand All @@ -176,30 +177,9 @@ public AuthRes shopOwnerSignUp(final ShopOwnerSignUpReq shopOwnerSignUpReq) {
.password(passwordEncoder.encode(shopOwnerSignUpReq.getPassword()))
.marketingConsent(shopOwnerSignUpReq.getMarketingConsent())
.build();

shopOwnerRepository.save(shopOwner);

UserPrincipal userPrincipal = UserPrincipal.createShopOwner(shopOwner);
Authentication authentication = new UsernamePasswordAuthenticationToken(
userPrincipal,
null,
userPrincipal.getAuthorities()
);

TokenMapping tokenMapping = customTokenProviderService.createToken(authentication);

Token token = Token.builder()
.refreshToken(tokenMapping.getRefreshToken())
.userEmail(tokenMapping.getUserEmail())
.build();
tokenRepository.save(token);

AuthRes authRes = AuthRes.builder()
.accessToken(tokenMapping.getAccessToken())
.refreshToken(token.getRefreshToken())
.build();

return authRes;
return getShopOwnerAuthRes(shopOwner);
}

@Transactional
Expand All @@ -211,27 +191,7 @@ public AuthRes shopOwnerSignIn(final ShopOwnerSignInReq shopOwnerSignInReq) {
throw new InvalidPasswordException();
}

UserPrincipal userPrincipal = UserPrincipal.createShopOwner(shopOwner);
Authentication authentication = new UsernamePasswordAuthenticationToken(
userPrincipal,
null,
userPrincipal.getAuthorities()
);

TokenMapping tokenMapping = customTokenProviderService.createToken(authentication);

Token token = Token.builder()
.refreshToken(tokenMapping.getRefreshToken())
.userEmail(tokenMapping.getUserEmail())
.build();
tokenRepository.save(token);

AuthRes authRes = AuthRes.builder()
.accessToken(tokenMapping.getAccessToken())
.refreshToken(token.getRefreshToken())
.build();

return authRes;
return getShopOwnerAuthRes(shopOwner);
}

@Transactional
Expand Down Expand Up @@ -262,24 +222,38 @@ private boolean valid(final String refreshToken) {
return true;
}

@Transactional
public AuthRes appleSignIn(AppleSignInReq appleSignInReq) {
Claims claims = appleJwtUtils.getClaimsBy(appleSignInReq.getIdentityToken());
String providerId = claims.get("sub").toString();
private AuthRes getUserAuthRes(User user) {
UserPrincipal userPrincipal = UserPrincipal.createUser(user);
Authentication authentication = new UsernamePasswordAuthenticationToken(
userPrincipal,
null,
userPrincipal.getAuthorities()
);

User user = userRepository.findByProviderId(providerId).orElseThrow(InvalidProviderIdException::new);
if(user.getName() == null || user.getPhoneNumber() == null || user.getAge() == null || user.getGender() == null) {
throw new UnRegisteredUserException();
}
TokenMapping tokenMapping = customTokenProviderService.createToken(authentication);
Token token = Token.builder()
.refreshToken(tokenMapping.getRefreshToken())
.userEmail(tokenMapping.getUserEmail())
.build();

UserPrincipal userPrincipal = UserPrincipal.createUser(user);
tokenRepository.save(token);

return AuthRes.builder()
.accessToken(tokenMapping.getAccessToken())
.refreshToken(token.getRefreshToken())
.build();
}

private AuthRes getShopOwnerAuthRes(ShopOwner shopOwner) {
UserPrincipal userPrincipal = UserPrincipal.createShopOwner(shopOwner);
Authentication authentication = new UsernamePasswordAuthenticationToken(
userPrincipal,
null,
userPrincipal.getAuthorities()
);

TokenMapping tokenMapping = customTokenProviderService.createToken(authentication);

Token token = Token.builder()
.refreshToken(tokenMapping.getRefreshToken())
.userEmail(tokenMapping.getUserEmail())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,6 @@ private User registerNewUser(OAuth2UserRequest oAuth2UserRequest, OAuth2UserInfo
.providerId(oAuth2UserInfo.getId())
.name(oAuth2UserInfo.getName())
.email(oAuth2UserInfo.getEmail())
.profileImgUrl(oAuth2UserInfo.getImageUrl())
.role(Role.USER)
.birthDay(oAuth2UserInfo.getBirthDay())
.build();
Expand All @@ -69,10 +68,7 @@ private User registerNewUser(OAuth2UserRequest oAuth2UserRequest, OAuth2UserInfo
}

private User updateExistingUser(User user, OAuth2UserInfo oAuth2UserInfo) {

user.updateName(oAuth2UserInfo.getName());
user.updateProfileImage(oAuth2UserInfo.getImageUrl());

return userRepository.save(user);
}

Expand Down
Loading

0 comments on commit 08f85fd

Please sign in to comment.