From 859a6d948c658d5ae528f975e20a066a0fa68978 Mon Sep 17 00:00:00 2001 From: kang Date: Sat, 10 Aug 2024 21:26:58 +0900 Subject: [PATCH 01/11] feat: rename --- src/main/java/co/orange/ddanzi/domain/user/enums/Sex.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/co/orange/ddanzi/domain/user/enums/Sex.java b/src/main/java/co/orange/ddanzi/domain/user/enums/Sex.java index 0d963361..5621b572 100644 --- a/src/main/java/co/orange/ddanzi/domain/user/enums/Sex.java +++ b/src/main/java/co/orange/ddanzi/domain/user/enums/Sex.java @@ -4,8 +4,8 @@ @Getter public enum Sex { - MAN("남"), - WOMAN("여") + MALE("MALE"), + FEMALE("FEMALE") ; private final String sex; Sex(String sex) { From 63b84db8132411ca62038444f6e34c3760571ed9 Mon Sep 17 00:00:00 2001 From: kang Date: Sat, 10 Aug 2024 23:39:57 +0900 Subject: [PATCH 02/11] feat: add create refresh token method --- .../ddanzi/global/config/jwt/JwtUtils.java | 24 +++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/src/main/java/co/orange/ddanzi/global/config/jwt/JwtUtils.java b/src/main/java/co/orange/ddanzi/global/config/jwt/JwtUtils.java index 224b8248..55962bc7 100644 --- a/src/main/java/co/orange/ddanzi/global/config/jwt/JwtUtils.java +++ b/src/main/java/co/orange/ddanzi/global/config/jwt/JwtUtils.java @@ -18,6 +18,7 @@ import java.util.Collections; import java.util.Date; +import java.util.concurrent.TimeUnit; @Slf4j @@ -36,9 +37,9 @@ public class JwtUtils { private final StringRedisTemplate stringRedisTemplate; - public String createAccessToken(String idToken) { + public String createAccessToken(String email) { Claims claims = Jwts.claims(); - claims.put("idToken", idToken); + claims.put("email", email); long validTime = accessTokenTime; Date now = new Date(); @@ -51,7 +52,26 @@ public String createAccessToken(String idToken) { .compact(); } + public String createRefreshToken(String email) { + Claims claims = Jwts.claims(); + claims.put("email", email); + long validTime = refreshTokenTime; + Date now = new Date(); + String refreshToken = Jwts.builder() + .setClaims(claims) + .setIssuedAt(now) + .setExpiration(new Date(now.getTime() + validTime)) + .signWith(SignatureAlgorithm.HS256, jwtSecretKey) + .compact(); + + updateUserRefreshToken(email, refreshToken); + return refreshToken; + } + + public void updateUserRefreshToken(String email, String refreshToken) { + stringRedisTemplate.opsForValue().set(email, refreshToken, refreshTokenTime, TimeUnit.MILLISECONDS); + } public String resolveJWT(HttpServletRequest request) { String bearerToken = request.getHeader("Authorization"); From 6c2a54062370dc54c9099cde4c5349da06a09369 Mon Sep 17 00:00:00 2001 From: kang Date: Sat, 10 Aug 2024 23:40:42 +0900 Subject: [PATCH 03/11] feat: create basic structure of kakao signin api --- .../ddanzi/controller/AuthController.java | 10 ++- .../co/orange/ddanzi/service/AuthService.java | 61 +++++++++++++++++++ 2 files changed, 69 insertions(+), 2 deletions(-) diff --git a/src/main/java/co/orange/ddanzi/controller/AuthController.java b/src/main/java/co/orange/ddanzi/controller/AuthController.java index f1813314..12146a24 100644 --- a/src/main/java/co/orange/ddanzi/controller/AuthController.java +++ b/src/main/java/co/orange/ddanzi/controller/AuthController.java @@ -3,6 +3,7 @@ import co.orange.ddanzi.dto.auth.LoginDto; import co.orange.ddanzi.global.common.response.ApiResponse; import co.orange.ddanzi.service.AuthService; +import com.fasterxml.jackson.core.JsonProcessingException; import lombok.RequiredArgsConstructor; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; @@ -16,7 +17,12 @@ public class AuthController { private final AuthService authService; @PostMapping("/signin/test") - ApiResponse signin(@RequestBody LoginDto requestDto){ - return authService.testSignin(requestDto.getIdToken()); + ApiResponse test(@RequestBody LoginDto requestDto){ + return authService.testSignin(requestDto.getToken()); + } + + @PostMapping("/signin") + ApiResponse signin(@RequestBody LoginDto requestDto) { + return authService.testSignin(requestDto.getToken()); } } diff --git a/src/main/java/co/orange/ddanzi/service/AuthService.java b/src/main/java/co/orange/ddanzi/service/AuthService.java index 3c3da45d..e8f65e23 100644 --- a/src/main/java/co/orange/ddanzi/service/AuthService.java +++ b/src/main/java/co/orange/ddanzi/service/AuthService.java @@ -2,15 +2,25 @@ import co.orange.ddanzi.domain.user.User; import co.orange.ddanzi.dto.auth.AuthResponseDto; +import co.orange.ddanzi.dto.auth.LoginResponseDto; import co.orange.ddanzi.global.common.error.Error; import co.orange.ddanzi.global.common.response.ApiResponse; import co.orange.ddanzi.global.common.response.Success; import co.orange.ddanzi.global.config.jwt.JwtUtils; import co.orange.ddanzi.repository.UserRepository; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; import jakarta.transaction.Transactional; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Service; +import org.springframework.util.MultiValueMap; +import org.springframework.web.client.RestTemplate; import java.util.Optional; @@ -37,6 +47,57 @@ public ApiResponse testSignin(String idToken){ .build(); return ApiResponse.onSuccess(Success.SUCCESS, responseDto); } + + @Transactional + public ApiResponse signinKakao(String token) throws JsonProcessingException { + String email = getKakaoEmail(token); + + User user = checkKakaoUserExist(email); + + LoginResponseDto responseDto = LoginResponseDto.builder() + .accesstoken(jwtUtils.createAccessToken(email)) + .refreshtoken(jwtUtils.createRefreshToken(email)) + .nickname("예시닉네임") + .build(); + } + + + public User checkKakaoUserExist (String email) { + // DB에 중복되는 email이 있는지 확인 + Optional user = userRepository.findByLoginId(email); + + // 회원가입 + if (user.isEmpty()) { + } + + return user.get(); + } + + public String getKakaoEmail(String accessToken) throws JsonProcessingException { + // HTTP Header 생성 + HttpHeaders headers = new HttpHeaders(); + headers.add("Authorization", "Bearer " + accessToken); + headers.add("Content-type", "application/x-www-form-urlencoded;charset=utf-8"); + + // HTTP 요청 보내기 + HttpEntity> kakaoUserInfoRequest = new HttpEntity<>(headers); + RestTemplate rt = new RestTemplate(); + ResponseEntity response = rt.exchange( + "https://kapi.kakao.com/v2/user/me", + HttpMethod.POST, + kakaoUserInfoRequest, + String.class + ); + + // responseBody에 있는 정보 꺼내기 + String responseBody = response.getBody(); + ObjectMapper objectMapper = new ObjectMapper(); + JsonNode jsonNode = objectMapper.readTree(responseBody); + + String email = jsonNode.get("kakao_account").get("email").asText(); + + return email; + } } From 6de488aff50368bb0cfe8f360b6368a7c9cb5702 Mon Sep 17 00:00:00 2001 From: kang Date: Sat, 10 Aug 2024 23:41:43 +0900 Subject: [PATCH 04/11] feat: create kakao signin req res dto --- .../auth/{LoginDto.java => SigninRequestDto.java} | 4 ++-- .../co/orange/ddanzi/dto/auth/SigninResponseDto.java | 12 ++++++++++++ 2 files changed, 14 insertions(+), 2 deletions(-) rename src/main/java/co/orange/ddanzi/dto/auth/{LoginDto.java => SigninRequestDto.java} (72%) create mode 100644 src/main/java/co/orange/ddanzi/dto/auth/SigninResponseDto.java diff --git a/src/main/java/co/orange/ddanzi/dto/auth/LoginDto.java b/src/main/java/co/orange/ddanzi/dto/auth/SigninRequestDto.java similarity index 72% rename from src/main/java/co/orange/ddanzi/dto/auth/LoginDto.java rename to src/main/java/co/orange/ddanzi/dto/auth/SigninRequestDto.java index 08d6a44c..23f2c673 100644 --- a/src/main/java/co/orange/ddanzi/dto/auth/LoginDto.java +++ b/src/main/java/co/orange/ddanzi/dto/auth/SigninRequestDto.java @@ -4,8 +4,8 @@ import lombok.Getter; @Getter -public class LoginDto { - private String idToken; +public class SigninRequestDto { + private String token; private LoginType type; } diff --git a/src/main/java/co/orange/ddanzi/dto/auth/SigninResponseDto.java b/src/main/java/co/orange/ddanzi/dto/auth/SigninResponseDto.java new file mode 100644 index 00000000..ee1e41ea --- /dev/null +++ b/src/main/java/co/orange/ddanzi/dto/auth/SigninResponseDto.java @@ -0,0 +1,12 @@ +package co.orange.ddanzi.dto.auth; + +import lombok.Builder; +import lombok.Getter; + +@Getter +@Builder +public class SigninResponseDto { + private String accesstoken; + private String refreshtoken; + private String nickname; +} From e16e58035b3c4c11653401b343e3d6dc42277982 Mon Sep 17 00:00:00 2001 From: kang Date: Sun, 11 Aug 2024 00:29:22 +0900 Subject: [PATCH 05/11] feat: add email field --- src/main/java/co/orange/ddanzi/domain/user/User.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/co/orange/ddanzi/domain/user/User.java b/src/main/java/co/orange/ddanzi/domain/user/User.java index 913f7819..636749db 100644 --- a/src/main/java/co/orange/ddanzi/domain/user/User.java +++ b/src/main/java/co/orange/ddanzi/domain/user/User.java @@ -18,8 +18,8 @@ public class User extends BaseTimeEntity { @Column(name = "user_id") private Long id; //유저 고유 ID - @Column(name = "login_id") - private String loginId; //로그인 ID + @Column(name = "email", nullable = false, length = 320) + private String email; //가입 이메일 @Enumerated(EnumType.STRING) @Column(name = "type") @@ -37,8 +37,8 @@ public class User extends BaseTimeEntity { private Authentication authentication; @Builder - public User(String loginId, LoginType type, String nickname, MemberStatus status) { - this.loginId = loginId; + public User(String email, LoginType type, String nickname, MemberStatus status) { + this.email = email; this.nickname = nickname; this.type = type; this.status = status; From 3debb59d7f157445e57caf3533255042b23f4a68 Mon Sep 17 00:00:00 2001 From: kang Date: Sun, 11 Aug 2024 00:29:30 +0900 Subject: [PATCH 06/11] feat: delete email field --- .../java/co/orange/ddanzi/domain/user/Authentication.java | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/main/java/co/orange/ddanzi/domain/user/Authentication.java b/src/main/java/co/orange/ddanzi/domain/user/Authentication.java index 2c19b46b..20cafce5 100644 --- a/src/main/java/co/orange/ddanzi/domain/user/Authentication.java +++ b/src/main/java/co/orange/ddanzi/domain/user/Authentication.java @@ -28,9 +28,6 @@ public class Authentication extends BaseTimeEntity { @Column(name = "name", nullable = false, length = 255) private String name; //이름 - @Column(name = "email", nullable = false, length = 320) - private String email; //이메일 - @Column(name = "phone", nullable = false, length = 15) private String phone; //전화번호 @@ -48,10 +45,9 @@ public class Authentication extends BaseTimeEntity { @Builder - public Authentication(User user, String name, String email, String phone, LocalDate birth, Sex sex, Nation nation) { + public Authentication(User user, String name, String phone, LocalDate birth, Sex sex, Nation nation) { this.user = user; this.name = name; - this.email = email; this.phone = phone; this.birth = birth; this.sex = sex; From 2a01e8d16d9385ac3bed8e4ac9abd143b03c275f Mon Sep 17 00:00:00 2001 From: kang Date: Sun, 11 Aug 2024 00:29:48 +0900 Subject: [PATCH 07/11] chore: add success msg for sign in --- .../java/co/orange/ddanzi/global/common/response/Success.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/java/co/orange/ddanzi/global/common/response/Success.java b/src/main/java/co/orange/ddanzi/global/common/response/Success.java index 3983570e..4c46c491 100644 --- a/src/main/java/co/orange/ddanzi/global/common/response/Success.java +++ b/src/main/java/co/orange/ddanzi/global/common/response/Success.java @@ -13,6 +13,9 @@ public enum Success { SUCCESS(HttpStatus.OK, "Request successfully processed."), // 200 OK SUCCESS + SIGNIN_KAKAO_SUCCESS(HttpStatus.CREATED, "Successfully sign in using Kakao"), + SIGNIN_APPLE_SUCCESS(HttpStatus.CREATED, "Successfully sign in using Kakao"), + GET_REDIS_KEY_SUCCESS(HttpStatus.CREATED, "Successfully retrieved the redis key"), GET_HOME_INFO_SUCCESS(HttpStatus.OK, "Successfully retrieved home information."), From 4e0c6106571ca4bcd45490a3010e80fccd12554e Mon Sep 17 00:00:00 2001 From: kang Date: Sun, 11 Aug 2024 03:18:22 +0900 Subject: [PATCH 08/11] chore: tiny modifications --- .../co/orange/ddanzi/domain/user/User.java | 8 ++++---- .../ddanzi/domain/user/enums/MemberStatus.java | 17 ----------------- .../ddanzi/domain/user/enums/UserStatus.java | 18 ++++++++++++++++++ .../ddanzi/global/config/jwt/AuthUtils.java | 4 ++-- .../ddanzi/global/config/jwt/JwtFilter.java | 1 - 5 files changed, 24 insertions(+), 24 deletions(-) delete mode 100644 src/main/java/co/orange/ddanzi/domain/user/enums/MemberStatus.java create mode 100644 src/main/java/co/orange/ddanzi/domain/user/enums/UserStatus.java diff --git a/src/main/java/co/orange/ddanzi/domain/user/User.java b/src/main/java/co/orange/ddanzi/domain/user/User.java index 636749db..6dab8a48 100644 --- a/src/main/java/co/orange/ddanzi/domain/user/User.java +++ b/src/main/java/co/orange/ddanzi/domain/user/User.java @@ -2,7 +2,7 @@ import co.orange.ddanzi.global.common.domain.BaseTimeEntity; import co.orange.ddanzi.domain.user.enums.LoginType; -import co.orange.ddanzi.domain.user.enums.MemberStatus; +import co.orange.ddanzi.domain.user.enums.UserStatus; import jakarta.persistence.*; import lombok.Builder; import lombok.Getter; @@ -25,19 +25,19 @@ public class User extends BaseTimeEntity { @Column(name = "type") private LoginType type; //로그인 타입(KAKAO/APPLE) - @Column(name = "nickname", nullable = false, length = 10) + @Column(name = "nickname", nullable = false, unique = true, length = 20) private String nickname; // 닉네임 -> 자동생성 @Enumerated(EnumType.STRING) @Column(name = "status") - private MemberStatus status; //상태(ACTIVATE/SLEEP/DELETE) + private UserStatus status; //상태(ACTIVATE/SLEEP/DELETE) @OneToOne(fetch = FetchType.LAZY) @JoinColumn(name = "authentication_id") private Authentication authentication; @Builder - public User(String email, LoginType type, String nickname, MemberStatus status) { + public User(String email, LoginType type, String nickname, UserStatus status) { this.email = email; this.nickname = nickname; this.type = type; diff --git a/src/main/java/co/orange/ddanzi/domain/user/enums/MemberStatus.java b/src/main/java/co/orange/ddanzi/domain/user/enums/MemberStatus.java deleted file mode 100644 index c8ae617a..00000000 --- a/src/main/java/co/orange/ddanzi/domain/user/enums/MemberStatus.java +++ /dev/null @@ -1,17 +0,0 @@ -package co.orange.ddanzi.domain.user.enums; - -import lombok.Getter; - -@Getter -public enum MemberStatus { - ACTIVATE("활성"), - SLEEP("휴면"), - DELETE("삭제") - ; - - private final String memberStatus; - MemberStatus(String memberStatus) { - this.memberStatus = memberStatus; - } - -} diff --git a/src/main/java/co/orange/ddanzi/domain/user/enums/UserStatus.java b/src/main/java/co/orange/ddanzi/domain/user/enums/UserStatus.java new file mode 100644 index 00000000..eac215c5 --- /dev/null +++ b/src/main/java/co/orange/ddanzi/domain/user/enums/UserStatus.java @@ -0,0 +1,18 @@ +package co.orange.ddanzi.domain.user.enums; + +import lombok.Getter; + +@Getter +public enum UserStatus { + UNAUTHENTICATED("인증안됨"), + ACTIVATE("활성"), + SLEEP("휴면"), + DELETE("삭제") + ; + + private final String userStatus; + UserStatus(String userStatus) { + this.userStatus = userStatus; + } + +} diff --git a/src/main/java/co/orange/ddanzi/global/config/jwt/AuthUtils.java b/src/main/java/co/orange/ddanzi/global/config/jwt/AuthUtils.java index 665c7100..b8d197c5 100644 --- a/src/main/java/co/orange/ddanzi/global/config/jwt/AuthUtils.java +++ b/src/main/java/co/orange/ddanzi/global/config/jwt/AuthUtils.java @@ -22,7 +22,7 @@ public User getUser() { if (currentUserNickname == null) { return null; } - return userRepository.findByLoginId(currentUserNickname) + return userRepository.findByEmail(currentUserNickname) .orElseThrow(() -> new UserNotFoundException()); } @@ -44,7 +44,7 @@ public String getCurrentUserNickname() { if (principalObject instanceof UserDetails) { UserDetails userDetails = (UserDetails) principalObject; - log.info("id token -> {}", userDetails.getUsername()); + log.info("email -> {}", userDetails.getUsername()); return userDetails.getUsername(); } return null; diff --git a/src/main/java/co/orange/ddanzi/global/config/jwt/JwtFilter.java b/src/main/java/co/orange/ddanzi/global/config/jwt/JwtFilter.java index e8110dd5..05eba876 100644 --- a/src/main/java/co/orange/ddanzi/global/config/jwt/JwtFilter.java +++ b/src/main/java/co/orange/ddanzi/global/config/jwt/JwtFilter.java @@ -40,7 +40,6 @@ protected void doFilterInternal(HttpServletRequest request, HttpServletResponse protected boolean shouldNotFilter(HttpServletRequest request) throws ServletException { String path = request.getRequestURI(); return path.startsWith("/api/v1/auth") - || path.equals("/api/v1/search") ; } } From b06d12d6af054827dc5bfe237b1f920d217e715f Mon Sep 17 00:00:00 2001 From: kang Date: Sun, 11 Aug 2024 03:18:44 +0900 Subject: [PATCH 09/11] feat: create txt files for generating nickname --- src/main/resources/nickname/adjectives.txt | 149 +++++++++++++++++++++ src/main/resources/nickname/animals.txt | 100 ++++++++++++++ 2 files changed, 249 insertions(+) create mode 100644 src/main/resources/nickname/adjectives.txt create mode 100644 src/main/resources/nickname/animals.txt diff --git a/src/main/resources/nickname/adjectives.txt b/src/main/resources/nickname/adjectives.txt new file mode 100644 index 00000000..fa6d4d61 --- /dev/null +++ b/src/main/resources/nickname/adjectives.txt @@ -0,0 +1,149 @@ +행복한 +귀여운 +사랑스러운 +따뜻한 +친절한 +멋진 +아름다운 +재미있는 +기쁜 +즐거운 +상냥한 +신나는 +유쾌한 +다정한 +밝은 +활기찬 +감동적인 +고마운 +만족스러운 +재밌는 +상쾌한 +신비로운 +꿈같은 +황홀한 +유머러스한 +매너있는 +설레는 +포근한 +차분한 +기분좋은 +흥미로운 +용감한 +긍정적인 +호감가는 +믿음직한 +정겨운 +사랑받는 +감격스러운 +뿌듯한 +안락한 +은은한 +짜릿한 +소중한 +훈훈한 +편안한 +기뻐하는 +평화로운 +자랑스러운 +진정한 +화사한 +활발한 +넉넉한 +든든한 +사랑스런 +화목한 +강렬한 +재미난 +감미로운 +부드러운 +푸근한 +미소짓는 +환상적인 +기막힌 +믿을만한 +훌륭한 +안도하는 +고요한 +자상한 +따사로운 +달콤한 +존경스러운 +아늑한 +흥미진진한 +기특한 +반가운 +반짝이는 +우아한 +기쁨의 +영롱한 +만족스런 +매혹적인 +눈부신 +다채로운 +활기넘치는 +신선한 +새콤달콤한 +명랑한 +웃음짓는 +산뜻한 +매력적인 +예쁜 +천진난만한 +순수한 +존경받는 +흥겨운 +열정적인 +자유로운 +창의적인 +독창적인 +평온한 +온화한 +생기있는 +호기심많은 +행복가득한 +희망찬 +이상적인 +특별한 +멋드러진 +용기있는 +가슴뛰는 +포용력있는 +참신한 +감사하는 +소박한 +순진한 +겸손한 +용서하는 +정감있는 +감격적인 +장엄한 +신비한 +자비로운 +즐거워하는 +평화스러운 +나긋나긋한 +영롱한 +눈부신 +진실한 +꾸밈없는 +해맑은 +담백한 +순진무구한 +깨끗한 +조용한 +신성한 +예리한 +진지한 +강인한 +친근한 +다정다감한 +낭만적인 +웃음가득한 +조화로운 +잔잔한 +사랑스러운 +환호하는 +동화같은 +감탄스러운 +안락한 \ No newline at end of file diff --git a/src/main/resources/nickname/animals.txt b/src/main/resources/nickname/animals.txt new file mode 100644 index 00000000..238c936d --- /dev/null +++ b/src/main/resources/nickname/animals.txt @@ -0,0 +1,100 @@ +사자 +호랑이 +코끼리 +기린 +얼룩말 +하마 +코뿔소 +표범 +치타 +늑대 +여우 +곰 +판다 +고릴라 +침팬지 +오랑우탄 +원숭이 +캥거루 +코알라 +나무늘보 +아르마딜로 +두더지 +사슴 +엘크 +무스 +다람쥐 +청설모 +비버 +토끼 +고슴도치 +족제비 +오소리 +스컹크 +너구리 +북극곰 +바다표범 +해달 +돌고래 +고래 +상어 +가오리 +문어 +오징어 +해마 +펭귄 +알바트로스 +갈매기 +독수리 +매 +올빼미 +부엉이 +앵무새 +까마귀 +까치 +참새 +제비 +비둘기 +꿩 +공작새 +타조 +닭 +오리 +거위 +백조 +플라밍고 +앵무새 +코뿔새 +나이팅게일 +벌새 +딱따구리 +두루미 +황새 +두꺼비 +개구리 +이구아나 +카멜레온 +악어 +거북이 +도마뱀 +뱀 +장어 +메기 +송어 +연어 +고등어 +참치 +정어리 +가자미 +넙치 +낙타 +당나귀 +말 +노새 +양 +염소 +돼지 +소 +개 +고양이 +햄스터 \ No newline at end of file From 6118d6fcdd12288fdbf82b39cc71ddb47b00eb0e Mon Sep 17 00:00:00 2001 From: kang Date: Sun, 11 Aug 2024 03:19:01 +0900 Subject: [PATCH 10/11] feat: create findByNickname jpa --- src/main/java/co/orange/ddanzi/repository/UserRepository.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/co/orange/ddanzi/repository/UserRepository.java b/src/main/java/co/orange/ddanzi/repository/UserRepository.java index a9e4861e..18379143 100644 --- a/src/main/java/co/orange/ddanzi/repository/UserRepository.java +++ b/src/main/java/co/orange/ddanzi/repository/UserRepository.java @@ -6,5 +6,7 @@ import java.util.Optional; public interface UserRepository extends CrudRepository { - Optional findByLoginId(String loginId); + Optional findByEmail(String email); + + Optional findByNickname(String nickname); } From be97e8e61d48ef14b30d9d06558c11572fc7ed71 Mon Sep 17 00:00:00 2001 From: kang Date: Sun, 11 Aug 2024 03:19:32 +0900 Subject: [PATCH 11/11] feat: create kakao signin api --- .../ddanzi/controller/AuthController.java | 11 ++- .../co/orange/ddanzi/service/AuthService.java | 83 +++++++++++++------ 2 files changed, 66 insertions(+), 28 deletions(-) diff --git a/src/main/java/co/orange/ddanzi/controller/AuthController.java b/src/main/java/co/orange/ddanzi/controller/AuthController.java index 12146a24..82493705 100644 --- a/src/main/java/co/orange/ddanzi/controller/AuthController.java +++ b/src/main/java/co/orange/ddanzi/controller/AuthController.java @@ -1,6 +1,7 @@ package co.orange.ddanzi.controller; -import co.orange.ddanzi.dto.auth.LoginDto; +import co.orange.ddanzi.domain.user.enums.LoginType; +import co.orange.ddanzi.dto.auth.SigninRequestDto; import co.orange.ddanzi.global.common.response.ApiResponse; import co.orange.ddanzi.service.AuthService; import com.fasterxml.jackson.core.JsonProcessingException; @@ -17,12 +18,14 @@ public class AuthController { private final AuthService authService; @PostMapping("/signin/test") - ApiResponse test(@RequestBody LoginDto requestDto){ + ApiResponse test(@RequestBody SigninRequestDto requestDto){ return authService.testSignin(requestDto.getToken()); } @PostMapping("/signin") - ApiResponse signin(@RequestBody LoginDto requestDto) { - return authService.testSignin(requestDto.getToken()); + ApiResponse signin(@RequestBody SigninRequestDto requestDto) throws JsonProcessingException { + if(requestDto.getType().equals(LoginType.KAKAO)) + return authService.kakaoSignIn(requestDto.getToken()); + return authService.kakaoSignIn(requestDto.getToken()); } } diff --git a/src/main/java/co/orange/ddanzi/service/AuthService.java b/src/main/java/co/orange/ddanzi/service/AuthService.java index e8f65e23..60ebd0a5 100644 --- a/src/main/java/co/orange/ddanzi/service/AuthService.java +++ b/src/main/java/co/orange/ddanzi/service/AuthService.java @@ -1,8 +1,10 @@ package co.orange.ddanzi.service; import co.orange.ddanzi.domain.user.User; +import co.orange.ddanzi.domain.user.enums.LoginType; +import co.orange.ddanzi.domain.user.enums.UserStatus; import co.orange.ddanzi.dto.auth.AuthResponseDto; -import co.orange.ddanzi.dto.auth.LoginResponseDto; +import co.orange.ddanzi.dto.auth.SigninResponseDto; import co.orange.ddanzi.global.common.error.Error; import co.orange.ddanzi.global.common.response.ApiResponse; import co.orange.ddanzi.global.common.response.Success; @@ -10,19 +12,24 @@ import co.orange.ddanzi.repository.UserRepository; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; import jakarta.transaction.Transactional; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.springframework.core.io.ClassPathResource; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Service; -import org.springframework.util.MultiValueMap; import org.springframework.web.client.RestTemplate; +import com.fasterxml.jackson.databind.ObjectMapper; -import java.util.Optional; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.*; +import java.util.stream.Collectors; @Slf4j @@ -35,61 +42,69 @@ public class AuthService { @Transactional public ApiResponse testSignin(String idToken){ - Optional optionalUser = userRepository.findByLoginId(idToken); + Optional optionalUser = userRepository.findByEmail(idToken); if(optionalUser.isEmpty()){ return ApiResponse.onFailure(Error.ERROR, null); } User user = optionalUser.get(); AuthResponseDto responseDto = AuthResponseDto.builder() - .accesstoken(jwtUtils.createAccessToken(user.getLoginId())) + .accesstoken(jwtUtils.createAccessToken(user.getEmail())) .nickname(user.getNickname()) .build(); return ApiResponse.onSuccess(Success.SUCCESS, responseDto); } @Transactional - public ApiResponse signinKakao(String token) throws JsonProcessingException { + public ApiResponse kakaoSignIn(String token) throws JsonProcessingException { + log.info("카카오 로그인 진입"); String email = getKakaoEmail(token); + log.info("카카오 이메일 조회 성공 email: {}", email); + Optional user = userRepository.findByEmail(email); - User user = checkKakaoUserExist(email); + if (user.isEmpty()){ + log.info("카카오 회원 가입 시작"); + kakaoSignUp(email); + user = userRepository.findByEmail(email); + } - LoginResponseDto responseDto = LoginResponseDto.builder() + SigninResponseDto responseDto = SigninResponseDto.builder() .accesstoken(jwtUtils.createAccessToken(email)) .refreshtoken(jwtUtils.createRefreshToken(email)) - .nickname("예시닉네임") + .nickname(user.get().getNickname()) .build(); + return ApiResponse.onSuccess(Success.SIGNIN_KAKAO_SUCCESS, responseDto); } - public User checkKakaoUserExist (String email) { - // DB에 중복되는 email이 있는지 확인 - Optional user = userRepository.findByLoginId(email); - - // 회원가입 - if (user.isEmpty()) { - } - - return user.get(); + public void kakaoSignUp(String email) { + User user = User.builder() + .email(email) + .type(LoginType.KAKAO) + .status(UserStatus.UNAUTHENTICATED) + .nickname(generateNickname()) + .build(); + userRepository.save(user); } public String getKakaoEmail(String accessToken) throws JsonProcessingException { - // HTTP Header 생성 + log.info("HTTP 해더 생성"); HttpHeaders headers = new HttpHeaders(); headers.add("Authorization", "Bearer " + accessToken); headers.add("Content-type", "application/x-www-form-urlencoded;charset=utf-8"); - // HTTP 요청 보내기 - HttpEntity> kakaoUserInfoRequest = new HttpEntity<>(headers); + log.info("HTTP 요청 보내기"); + HttpEntity kakaoUserInfoRequest = new HttpEntity<>(headers); RestTemplate rt = new RestTemplate(); + ResponseEntity response = rt.exchange( "https://kapi.kakao.com/v2/user/me", - HttpMethod.POST, + HttpMethod.GET, kakaoUserInfoRequest, String.class ); - // responseBody에 있는 정보 꺼내기 + log.info("응답 수신 성공"); String responseBody = response.getBody(); ObjectMapper objectMapper = new ObjectMapper(); JsonNode jsonNode = objectMapper.readTree(responseBody); @@ -98,6 +113,26 @@ public String getKakaoEmail(String accessToken) throws JsonProcessingException { return email; } + + private List loadWordsFromFile(String classpath) throws IOException { + ClassPathResource resource = new ClassPathResource(classpath); + try (BufferedReader reader = new BufferedReader(new InputStreamReader(resource.getInputStream()))) { + return reader.lines().collect(Collectors.toList()); + } + } + private String generateNickname() { + try { + List adjectives = loadWordsFromFile("nickname/adjectives.txt"); + List animals = loadWordsFromFile("nickname/animals.txt"); + String selectedAdjectives = adjectives.get(new Random().nextInt(adjectives.size())); + String selectedAnimals = animals.get(new Random().nextInt(animals.size())); + int randomSuffix = (int) (Math.random() * 100); + return selectedAdjectives + selectedAnimals + randomSuffix; + } catch (IOException e) { + e.printStackTrace(); + return null; + } + } }