11package com .back .web7_9_codecrete_be .domain .auth .service ;
22
3+ import com .back .web7_9_codecrete_be .domain .auth .dto .kakao .KakaoUserInfo ;
34import com .back .web7_9_codecrete_be .domain .auth .dto .request .LoginRequest ;
45import com .back .web7_9_codecrete_be .domain .auth .dto .request .SignupRequest ;
56import com .back .web7_9_codecrete_be .domain .auth .dto .response .LoginResponse ;
67import com .back .web7_9_codecrete_be .domain .email .service .EmailService ;
8+ import com .back .web7_9_codecrete_be .domain .users .entity .SocialType ;
79import com .back .web7_9_codecrete_be .domain .users .entity .User ;
810import com .back .web7_9_codecrete_be .domain .users .repository .UserRepository ;
911import com .back .web7_9_codecrete_be .global .error .code .AuthErrorCode ;
@@ -25,6 +27,7 @@ public class AuthService {
2527 private final PasswordEncoder passwordEncoder ;
2628 private final EmailService emailService ;
2729 private final TokenService tokenService ;
30+ private final KakaoOAuthService kakaoOAuthService ;
2831
2932 // 회원가입
3033 public void signUp (SignupRequest req ) {
@@ -50,6 +53,8 @@ public void signUp(SignupRequest req) {
5053 .password (passwordEncoder .encode (req .getPassword ()))
5154 .birth (LocalDate .parse (req .getBirth ()))
5255 .profileImage (req .getProfileImage ())
56+ .socialType (SocialType .LOCAL )
57+ .socialId (null )
5358 .build ();
5459
5560 userRepository .save (user );
@@ -66,6 +71,10 @@ public LoginResponse login(LoginRequest req) {
6671 throw new BusinessException (UserErrorCode .USER_DELETED );
6772 }
6873
74+ if (user .getSocialType () != SocialType .LOCAL ) {
75+ throw new BusinessException (AuthErrorCode .SOCIAL_USER_CANNOT_LOGIN );
76+ }
77+
6978 if (!passwordEncoder .matches (req .getPassword (), user .getPassword ())) {
7079 throw new BusinessException (AuthErrorCode .INVALID_PASSWORD );
7180 }
@@ -119,4 +128,61 @@ private String generateTempPassword() {
119128 }
120129 return sb .toString ();
121130 }
131+
132+ @ Transactional
133+ public LoginResponse kakaoLogin (String code ) {
134+
135+ // 1. 인가 코드 → 카카오 Access Token
136+ String kakaoAccessToken = kakaoOAuthService .getAccessToken (code );
137+
138+ // 2. Access Token → 사용자 정보
139+ KakaoUserInfo kakaoUserInfo = kakaoOAuthService .getUserInfo (kakaoAccessToken );
140+
141+ if (kakaoUserInfo .getEmail () == null ) {
142+ throw new BusinessException (AuthErrorCode .SOCIAL_EMAIL_NOT_PROVIDED );
143+ }
144+
145+ // 3. 소셜 ID 기준 사용자 조회
146+ User user = userRepository
147+ .findBySocialTypeAndSocialId (
148+ SocialType .KAKAO ,
149+ kakaoUserInfo .getSocialId ()
150+ )
151+ .orElseGet (() -> registerKakaoUser (kakaoUserInfo ));
152+
153+ // 4. 탈퇴 사용자 체크
154+ if (user .getIsDeleted ()) {
155+ throw new BusinessException (UserErrorCode .USER_DELETED );
156+ }
157+
158+ // 5. 토큰 발급
159+ tokenService .issueTokens (user );
160+
161+ return new LoginResponse (user .getId (), user .getNickname ());
162+ }
163+
164+ private User registerKakaoUser (KakaoUserInfo info ) {
165+
166+ String nickname = info .getNickname ();
167+ if (userRepository .existsByNickname (nickname )) {
168+ nickname = nickname + "_" + System .currentTimeMillis ();
169+ }
170+
171+ User user = User .builder ()
172+ .email (info .getEmail ())
173+ .nickname (nickname )
174+ .password (null )
175+ .birth (null )
176+ .profileImage (info .getProfileImageUrl ())
177+ .socialType (SocialType .KAKAO )
178+ .socialId (info .getSocialId ())
179+ .build ();
180+
181+ return userRepository .save (user );
182+ }
183+
184+ public LoginResponse googleLogin (String code ) {
185+ // TODO: 구글 인가 코드 → 사용자 정보 → 로그인 처리
186+ throw new UnsupportedOperationException ("구글 로그인 미구현" );
187+ }
122188}
0 commit comments