diff --git a/build.gradle b/build.gradle index facd766..15e5a1e 100644 --- a/build.gradle +++ b/build.gradle @@ -61,6 +61,7 @@ dependencies { //Apple Login implementation 'com.nimbusds:nimbus-jose-jwt:3.10' + implementation 'org.bouncycastle:bcpkix-jdk18on:1.72' //Json implementation 'com.googlecode.json-simple:json-simple:1.1.1' diff --git a/src/main/java/meltingpot/server/auth/oauth/OAuthDto.java b/src/main/java/meltingpot/server/auth/oauth/OAuthDto.java new file mode 100644 index 0000000..654059f --- /dev/null +++ b/src/main/java/meltingpot/server/auth/oauth/OAuthDto.java @@ -0,0 +1,12 @@ +package meltingpot.server.auth.oauth; + +import lombok.Builder; +import lombok.Getter; + +@Builder +@Getter +public class OAuthDto { + private String email; + private String nickname; + +} \ No newline at end of file diff --git a/src/main/java/meltingpot/server/auth/service/AuthService.java b/src/main/java/meltingpot/server/auth/service/AuthService.java index 94f56af..1ceb488 100644 --- a/src/main/java/meltingpot/server/auth/service/AuthService.java +++ b/src/main/java/meltingpot/server/auth/service/AuthService.java @@ -106,7 +106,7 @@ public AccountResponseDto signup(SignupRequestDto signupRequest) { .birth(signupRequest.birth()) .nationality(signupRequest.nationality()) .isQuit(false) - .oAuthType(OAuthType.NONE) + .OAuthType(OAuthType.NONE) .build(); account.setProfileImages(signupRequest.profileImages().stream().map( diff --git a/src/main/java/meltingpot/server/auth/service/OAuthService.java b/src/main/java/meltingpot/server/auth/service/OAuthService.java index ab97ca8..bad420f 100644 --- a/src/main/java/meltingpot/server/auth/service/OAuthService.java +++ b/src/main/java/meltingpot/server/auth/service/OAuthService.java @@ -1,18 +1,18 @@ package meltingpot.server.auth.service; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import meltingpot.server.auth.controller.dto.OAuthSignInRequestDto; import meltingpot.server.auth.controller.dto.OAuthSignupRequestDto; import meltingpot.server.auth.controller.dto.ProfileImageRequestDto; import meltingpot.server.auth.oauth.OAuthUserDetails; -import meltingpot.server.auth.oauth.kakao.KakaoDto; -import meltingpot.server.auth.oauth.kakao.KakaoService; +import meltingpot.server.auth.oauth.OAuthDto; import meltingpot.server.auth.service.dto.OAuthSignInResponseDto; import meltingpot.server.config.TokenProvider; import meltingpot.server.domain.entity.*; import meltingpot.server.domain.entity.enums.Gender; -import meltingpot.server.domain.entity.enums.OAuthType; import meltingpot.server.domain.repository.AccountPushTokenRepository; import meltingpot.server.domain.repository.AccountRepository; import meltingpot.server.domain.repository.RefreshTokenRepository; @@ -27,10 +27,7 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import java.util.HashSet; -import java.util.NoSuchElementException; -import java.util.Optional; -import java.util.Set; +import java.util.*; @Slf4j @RequiredArgsConstructor @@ -38,11 +35,10 @@ @EnableWebSecurity public class OAuthService { private final AccountRepository accountRepository; - private final KakaoService kakaoService; private final TokenProvider tokenProvider; private final RefreshTokenRepository refreshTokenRepository; private final AccountPushTokenRepository accountPushTokenRepository; - + private final ObjectMapper objectMapper = new ObjectMapper(); // SNS 회원 가입 @Transactional @@ -90,7 +86,7 @@ public OAuthSignInResponseDto oauthSignup(OAuthSignupRequestDto signupRequest) { .birth(signupRequest.birth()) .nationality(signupRequest.nationality()) .isQuit(false) - .oAuthType(signupRequest.OauthType()) + .OAuthType(signupRequest.OauthType()) .build(); account.setProfileImages(signupRequest.profileImages().stream().map( @@ -126,49 +122,27 @@ public OAuthSignInResponseDto oauthSignup(OAuthSignupRequestDto signupRequest) { @Transactional public OAuthSignInResponseDto SNSLogin(OAuthSignInRequestDto request) throws Exception { - if(request.type() == OAuthType.KAKAO) { - - /* * * * RestAPI 버전 * * * / - // 카카오 토큰 가져오기 - KaKaoTokenDto tokenDto = kakaoService.getKakaoToken(request.token()); - - // 카카오 유저 정보 가져오기 - KakaoDto kakaoDto = kakaoService.getUserInfoWithToken(request.token()); - * * * * * * * * * * * * */ - - // SDK 버전: 아이디토큰으로 유저 정보 파싱해오기 - KakaoDto kakaoDto = kakaoService.getUserInfoFromIdToken(request.token()); - - // 이미 가입한 회원인지 확인 - Optional account = accountRepository.findByUsernameAndIsQuitIsFalse(kakaoDto.getEmail()); - if (account.isEmpty()) { + OAuthDto oAuthDto = getUserInfoFromIdToken(request.token()); - // 회원 가입이 필요한 경우 - return OAuthSignInResponseDto.builder() - .register_required(true) - .nickName(kakaoDto.getNickname()) - .email(kakaoDto.getEmail()) - .tokenDto(null) - .build(); + // 이미 가입한 회원인지 확인 + Optional account = accountRepository.findByUsernameAndIsQuitFalseAndOAuthType(oAuthDto.getEmail(), request.type()); + if (account.isEmpty()) { - } else { + // 회원 가입이 필요한 경우 + return OAuthSignInResponseDto.builder() + .register_required(true) + .nickName(oAuthDto.getNickname()) + .email(oAuthDto.getEmail()) + .tokenDto(null) + .build(); - return OAuthSignInResponseDto.builder(). - register_required(false) - .nickName(kakaoDto.getNickname()) - .email(kakaoDto.getEmail()) - .tokenDto(setSecurityContext(account.get(), request.push_token())) - .build(); - } - } -// else if(request.type() == OAuthType.APPLE) { -// -// } -// else if(request.type() == OAuthType.GOOGLE) { -// -// } - else { - throw new NoSuchElementException(); + } else { + return OAuthSignInResponseDto.builder(). + register_required(false) + .nickName(oAuthDto.getNickname()) + .email(oAuthDto.getEmail()) + .tokenDto(setSecurityContext(account.get(), request.push_token())) + .build(); } } @@ -208,4 +182,29 @@ public TokenDto setSecurityContext(Account account, String pushToken ){ } + public OAuthDto getUserInfoFromIdToken(String idToken) throws Exception { + + // 온점 분리 + String[] parts = idToken.split("\\."); + if (parts.length != 3) { + throw new java.lang.IllegalArgumentException("Invalid IdToken"); + } + + // Payload 디코딩 + String payload = parts[1]; + String decodedPayload = new String(Base64.getDecoder().decode(payload)); + + // JSON 파싱 + JsonNode jsonNode = objectMapper.readTree(decodedPayload); + + // email과 nickname 추출 + String email = jsonNode.path("email").asText(null); + String nickname = jsonNode.path("nickname").asText(null); + + return OAuthDto.builder() + .email(email) + .nickname(nickname).build(); + + } + } diff --git a/src/main/java/meltingpot/server/domain/entity/Account.java b/src/main/java/meltingpot/server/domain/entity/Account.java index 6521063..d33de76 100644 --- a/src/main/java/meltingpot/server/domain/entity/Account.java +++ b/src/main/java/meltingpot/server/domain/entity/Account.java @@ -61,7 +61,8 @@ public class Account extends BaseEntity { private Boolean isQuit; // 탈퇴 여부 - private OAuthType oAuthType; + @Enumerated(EnumType.STRING) + private OAuthType OAuthType; @OneToMany(mappedBy = "account", cascade = CascadeType.ALL, fetch = FetchType.EAGER) @Builder.Default diff --git a/src/main/java/meltingpot/server/domain/repository/AccountRepository.java b/src/main/java/meltingpot/server/domain/repository/AccountRepository.java index a3230c6..f8974de 100644 --- a/src/main/java/meltingpot/server/domain/repository/AccountRepository.java +++ b/src/main/java/meltingpot/server/domain/repository/AccountRepository.java @@ -1,6 +1,7 @@ package meltingpot.server.domain.repository; import meltingpot.server.domain.entity.Account; +import meltingpot.server.domain.entity.enums.OAuthType; import org.springframework.data.jpa.repository.EntityGraph; import org.springframework.data.jpa.repository.JpaRepository; @@ -8,6 +9,7 @@ public interface AccountRepository extends JpaRepository { Optional findByUsernameAndIsQuitIsFalse(String username); + Optional findByUsernameAndIsQuitFalseAndOAuthType(String username, OAuthType oAuthType); Optional findByUsername(String name); boolean existsByUsername(String username);