11package com .example .ai_tutor .domain .auth .application ;
22
33import com .example .ai_tutor .domain .auth .domain .Token ;
4- import com .example .ai_tutor .domain .auth .dto .SignInReq ;
4+ import com .example .ai_tutor .domain .auth .dto .* ;
55import com .example .ai_tutor .domain .auth .exception .InvalidTokenException ;
66import com .example .ai_tutor .domain .auth .domain .repository .TokenRepository ;
7- import com .example .ai_tutor .domain .auth .dto .AuthRes ;
8- import com .example .ai_tutor .domain .auth .dto .RefreshTokenReq ;
9- import com .example .ai_tutor .domain .auth .dto .TokenMapping ;
107import com .example .ai_tutor .domain .professor .domain .repository .ProfessorRepository ;
118import com .example .ai_tutor .domain .user .domain .Provider ;
129import com .example .ai_tutor .domain .user .domain .User ;
1310import com .example .ai_tutor .domain .user .domain .repository .UserRepository ;
1411import com .example .ai_tutor .global .DefaultAssert ;
1512import com .example .ai_tutor .global .config .security .token .UserPrincipal ;
16- import com .example .ai_tutor .global .error .DefaultException ;
1713import com .example .ai_tutor .global .payload .ApiResponse ;
18- import com .example .ai_tutor .global .payload .ErrorCode ;
1914import com .example .ai_tutor .global .payload .Message ;
2015import lombok .RequiredArgsConstructor ;
2116import org .springframework .http .ResponseEntity ;
2217import org .springframework .security .authentication .AuthenticationManager ;
2318import org .springframework .security .authentication .UsernamePasswordAuthenticationToken ;
2419import org .springframework .security .core .Authentication ;
2520import org .springframework .security .core .context .SecurityContextHolder ;
21+ import org .springframework .security .core .userdetails .UserDetails ;
22+ import org .springframework .security .core .userdetails .UserDetailsService ;
2623import org .springframework .stereotype .Service ;
2724import org .springframework .transaction .annotation .Transactional ;
25+ import org .springframework .web .bind .annotation .RequestHeader ;
2826
2927import java .util .Optional ;
3028
@@ -35,6 +33,8 @@ public class AuthService {
3533
3634 private final CustomTokenProviderService customTokenProviderService ;
3735 private final AuthenticationManager authenticationManager ;
36+ private final IdTokenVerifier idTokenVerifier ;
37+ private final UserDetailsService userDetailsService ;
3838
3939 private final TokenRepository tokenRepository ;
4040 private final UserRepository userRepository ;
@@ -108,33 +108,46 @@ private boolean valid(String refreshToken){
108108 return true ;
109109 }
110110
111+
111112 @ Transactional
112- public ResponseEntity <?> signIn (SignInReq signInReq ) {
113- String email = signInReq . getEmail ();
114- // 유저 조회
115- User user = userRepository . findByEmail ( email )
116- . orElseThrow (() -> new DefaultException ( ErrorCode . INVALID_CHECK , "유저 정보가 유효하지 않습니다." ));
113+ public ResponseEntity <?> signIn (SignInReq signInReq , @ RequestHeader ( "Authorization" ) String authorizationHeader ) {
114+ // 1. 토큰 파싱
115+ String googleAccessToken = authorizationHeader . replace ( "Bearer " , "" ). trim ();
116+
117+ UserInfo userInfo = idTokenVerifier . verifyIdToken ( googleAccessToken , signInReq . getEmail ( ));
117118
119+ // 2. ID 토큰 검증 및 사용자 정보 추출
120+ if (userInfo == null ) {
121+ throw new RuntimeException ("유효하지 않은 ID 토큰" );
122+ }
123+ User user = userRepository .findByEmail (userInfo .getEmail ())
124+ .orElseGet (() -> {
125+ User newUser = User .builder ()
126+ .email (userInfo .getEmail ())
127+ .name (userInfo .getName ())
128+ .password ("oauth-only" )
129+ .provider (Provider .google )
130+ .providerId (signInReq .getProviderId ())
131+ .build ();
132+ return userRepository .save (newUser );
133+ });
134+
135+ // 4. Spring Security 인증 객체 생성
118136 // 인증 객체 생성 및 SecurityContext 등록
119- Authentication authentication = authenticationManager .authenticate (
120- new UsernamePasswordAuthenticationToken (
121- signInReq .getEmail (),
122- signInReq .getProviderId ()
123- )
124- );
137+ UserDetails userDetails = userDetailsService .loadUserByUsername (user .getEmail ());
138+ UsernamePasswordAuthenticationToken authentication =
139+ new UsernamePasswordAuthenticationToken (userDetails , null , userDetails .getAuthorities ());
125140 SecurityContextHolder .getContext ().setAuthentication (authentication );
126-
127- // JWT 토큰 생성
141+ // 5. JWT 토큰 생성 및 refresh 저장
128142 TokenMapping tokenMapping = customTokenProviderService .createToken (authentication );
129143
130- // 리프레시 토큰 DB 저장
131144 Token token = Token .builder ()
145+ .userEmail (user .getEmail ())
132146 .refreshToken (tokenMapping .getRefreshToken ())
133- .userEmail (tokenMapping .getEmail ())
134147 .build ();
135148 tokenRepository .save (token );
136149
137- // 응답 DTO 생성
150+ // 6. 응답 구성
138151 AuthRes authResponse = AuthRes .builder ()
139152 .accessToken (tokenMapping .getAccessToken ())
140153 .refreshToken (token .getRefreshToken ())
@@ -148,4 +161,7 @@ public ResponseEntity<?> signIn(SignInReq signInReq) {
148161 return ResponseEntity .ok (apiResponse );
149162 }
150163
164+
165+
166+
151167}
0 commit comments