99import com .ai .lawyer .global .jwt .CookieUtil ;
1010import com .ai .lawyer .global .email .service .EmailService ;
1111import com .ai .lawyer .global .email .service .EmailAuthService ;
12- import lombok .RequiredArgsConstructor ;
12+ import lombok .extern . slf4j . Slf4j ;
1313import org .springframework .security .crypto .password .PasswordEncoder ;
1414import org .springframework .stereotype .Service ;
1515import org .springframework .transaction .annotation .Transactional ;
1616import jakarta .servlet .http .HttpServletResponse ;
1717
18+ @ Slf4j
1819@ Service
19- @ RequiredArgsConstructor
2020@ Transactional (readOnly = true )
2121public class MemberService {
2222
2323 private final MemberRepository memberRepository ;
24- private final OAuth2MemberRepository oauth2MemberRepository ;
24+ private OAuth2MemberRepository oauth2MemberRepository ;
2525 private final PasswordEncoder passwordEncoder ;
2626 private final TokenProvider tokenProvider ;
2727 private final CookieUtil cookieUtil ;
2828 private final EmailService emailService ;
2929 private final EmailAuthService emailAuthService ;
3030
31+ public MemberService (
32+ MemberRepository memberRepository ,
33+ PasswordEncoder passwordEncoder ,
34+ TokenProvider tokenProvider ,
35+ CookieUtil cookieUtil ,
36+ EmailService emailService ,
37+ EmailAuthService emailAuthService ) {
38+ this .memberRepository = memberRepository ;
39+ this .passwordEncoder = passwordEncoder ;
40+ this .tokenProvider = tokenProvider ;
41+ this .cookieUtil = cookieUtil ;
42+ this .emailService = emailService ;
43+ this .emailAuthService = emailAuthService ;
44+ }
45+
46+ @ org .springframework .beans .factory .annotation .Autowired (required = false )
47+ public void setOauth2MemberRepository (OAuth2MemberRepository oauth2MemberRepository ) {
48+ this .oauth2MemberRepository = oauth2MemberRepository ;
49+ }
50+
51+ // 에러 메시지 상수
52+ private static final String ERR_DUPLICATE_EMAIL = "이미 존재하는 이메일입니다." ;
53+ private static final String ERR_MEMBER_NOT_FOUND = "존재하지 않는 회원입니다." ;
54+ private static final String ERR_PASSWORD_MISMATCH = "비밀번호가 일치하지 않습니다." ;
55+ private static final String ERR_INVALID_REFRESH_TOKEN = "유효하지 않은 리프레시 토큰입니다." ;
56+ private static final String ERR_MEMBER_NOT_FOUND_BY_LOGIN_ID = "해당 로그인 ID의 회원이 없습니다." ;
57+ private static final String ERR_EMAIL_VERIFICATION_REQUIRED = "이메일 인증을 완료해야 비밀번호를 재설정할 수 있습니다." ;
58+
3159 @ Transactional
3260 public MemberResponse signup (MemberSignupRequest request , HttpServletResponse response ) {
3361 validateDuplicateLoginId (request .getLoginId ());
@@ -52,10 +80,10 @@ public MemberResponse signup(MemberSignupRequest request, HttpServletResponse re
5280
5381 public MemberResponse login (MemberLoginRequest request , HttpServletResponse response ) {
5482 Member member = memberRepository .findByLoginId (request .getLoginId ())
55- .orElseThrow (() -> new IllegalArgumentException ("존재하지 않는 회원입니다." ));
83+ .orElseThrow (() -> new IllegalArgumentException (ERR_MEMBER_NOT_FOUND ));
5684
5785 if (!passwordEncoder .matches (request .getPassword (), member .getPassword ())) {
58- throw new IllegalArgumentException ("비밀번호가 일치하지 않습니다." );
86+ throw new IllegalArgumentException (ERR_PASSWORD_MISMATCH );
5987 }
6088
6189 String accessToken = tokenProvider .generateAccessToken (member );
@@ -74,74 +102,96 @@ public void logout(String loginId, HttpServletResponse response) {
74102 }
75103
76104 public MemberResponse refreshToken (String refreshToken , HttpServletResponse response ) {
105+ log .debug ("토큰 재발급 시작: refreshToken={}" , refreshToken .substring (0 , Math .min (10 , refreshToken .length ())) + "..." );
106+
107+ // 1. 리프레시 토큰으로 loginId 찾기
77108 String loginId = tokenProvider .findUsernameByRefreshToken (refreshToken );
78109 if (loginId == null ) {
79- throw new IllegalArgumentException ("유효하지 않은 리프레시 토큰입니다." );
110+ log .warn ("Redis에서 리프레시 토큰을 찾을 수 없습니다." );
111+ throw new IllegalArgumentException (ERR_INVALID_REFRESH_TOKEN );
80112 }
113+ log .debug ("리프레시 토큰으로 찾은 loginId: {}" , loginId );
81114
115+ // 2. 리프레시 토큰 검증
82116 if (!tokenProvider .validateRefreshToken (loginId , refreshToken )) {
83- throw new IllegalArgumentException ("유효하지 않은 리프레시 토큰입니다." );
117+ log .warn ("리프레시 토큰 검증 실패: loginId={}" , loginId );
118+ throw new IllegalArgumentException (ERR_INVALID_REFRESH_TOKEN );
84119 }
85120
86- // Member 또는 OAuth2Member 조회
87- com .ai .lawyer .domain .member .entity .MemberAdapter member = memberRepository .findByLoginId (loginId )
88- .map (m -> (com .ai .lawyer .domain .member .entity .MemberAdapter ) m )
89- .orElse (oauth2MemberRepository .findByLoginId (loginId ).orElse (null ));
121+ // 3. Member 또는 OAuth2Member 조회
122+ com .ai .lawyer .domain .member .entity .MemberAdapter member = memberRepository .findByLoginId (loginId ).orElse (null );
123+
124+ if (member != null ) {
125+ log .info ("로컬 회원 찾음: loginId={}, memberId={}" , loginId , member .getMemberId ());
126+ } else if (oauth2MemberRepository != null ) {
127+ member = oauth2MemberRepository .findByLoginId (loginId ).orElse (null );
128+ if (member != null ) {
129+ log .info ("OAuth2 회원 찾음: loginId={}, memberId={}" , loginId , member .getMemberId ());
130+ }
131+ }
90132
91133 if (member == null ) {
92- throw new IllegalArgumentException ("존재하지 않는 회원입니다." );
134+ log .error ("회원을 찾을 수 없습니다: loginId={}" , loginId );
135+ throw new IllegalArgumentException (ERR_MEMBER_NOT_FOUND );
93136 }
94137
138+ // 4. 기존 토큰 삭제
95139 tokenProvider .deleteAllTokens (loginId );
140+ log .debug ("기존 토큰 삭제 완료: loginId={}" , loginId );
96141
142+ // 5. 새 토큰 생성
97143 String newAccessToken = tokenProvider .generateAccessToken (member );
98144 String newRefreshToken = tokenProvider .generateRefreshToken (member );
145+ log .debug ("새 토큰 생성 완료: loginId={}" , loginId );
99146
147+ // 6. 쿠키 설정
100148 cookieUtil .setTokenCookies (response , newAccessToken , newRefreshToken );
149+ log .info ("토큰 재발급 성공: loginId={}, memberId={}, memberType={}" ,
150+ loginId , member .getMemberId (), member .getClass ().getSimpleName ());
101151
102152 return MemberResponse .from (member );
103153 }
104154
105155 @ Transactional
106156 public void withdraw (Long memberId ) {
107157 Member member = memberRepository .findById (memberId )
108- .orElseThrow (() -> new IllegalArgumentException ("존재하지 않는 회원입니다." ));
158+ .orElseThrow (() -> new IllegalArgumentException (ERR_MEMBER_NOT_FOUND ));
109159
110160 memberRepository .delete (member );
111161 }
112162
113163 public MemberResponse getMemberById (Long memberId ) {
114164 // Member 또는 OAuth2Member 조회
115- com .ai .lawyer .domain .member .entity .MemberAdapter member = memberRepository .findById (memberId )
116- . map ( m -> ( com . ai . lawyer . domain . member . entity . MemberAdapter ) m )
117- . orElse ( oauth2MemberRepository . findById ( memberId )
118- . map ( m -> ( com . ai . lawyer . domain . member . entity . MemberAdapter ) m )
119- . orElse ( null ));
165+ com .ai .lawyer .domain .member .entity .MemberAdapter member = memberRepository .findById (memberId ). orElse ( null );
166+
167+ if ( member == null && oauth2MemberRepository != null ) {
168+ member = oauth2MemberRepository . findById ( memberId ). orElse ( null );
169+ }
120170
121171 if (member == null ) {
122- throw new IllegalArgumentException ("존재하지 않는 회원입니다." );
172+ throw new IllegalArgumentException (ERR_MEMBER_NOT_FOUND );
123173 }
124174
125175 return MemberResponse .from (member );
126176 }
127177
128178 public void sendCodeToEmailByLoginId (String loginId ) {
129179 Member member = memberRepository .findByLoginId (loginId )
130- .orElseThrow (() -> new IllegalArgumentException ("해당 로그인 ID의 회원이 없습니다." ));
180+ .orElseThrow (() -> new IllegalArgumentException (ERR_MEMBER_NOT_FOUND_BY_LOGIN_ID ));
131181 String email = member .getLoginId ();
132182 emailService .sendVerificationCode (email , loginId );
133183 }
134184
135185 public boolean verifyAuthCode (String loginId , String verificationCode ) {
136186 memberRepository .findByLoginId (loginId )
137- .orElseThrow (() -> new IllegalArgumentException ("존재하지 않는 회원입니다." ));
187+ .orElseThrow (() -> new IllegalArgumentException (ERR_MEMBER_NOT_FOUND ));
138188
139189 return emailAuthService .verifyAuthCode (loginId , verificationCode );
140190 }
141191
142192 public boolean verifyPassword (String loginId , String password ) {
143193 Member member = memberRepository .findByLoginId (loginId )
144- .orElseThrow (() -> new IllegalArgumentException ("존재하지 않는 회원입니다." ));
194+ .orElseThrow (() -> new IllegalArgumentException (ERR_MEMBER_NOT_FOUND ));
145195
146196 boolean isValid = passwordEncoder .matches (password , member .getPassword ());
147197
@@ -156,17 +206,17 @@ public boolean verifyPassword(String loginId, String password) {
156206 @ Transactional
157207 public void resetPassword (String loginId , String newPassword , Boolean success ) {
158208 Member member = memberRepository .findByLoginId (loginId )
159- .orElseThrow (() -> new IllegalArgumentException ("존재하지 않는 회원입니다." ));
209+ .orElseThrow (() -> new IllegalArgumentException (ERR_MEMBER_NOT_FOUND ));
160210
161211 boolean clientSuccess = Boolean .TRUE .equals (success );
162212
163213 if (!clientSuccess ) {
164- throw new IllegalArgumentException ("이메일 인증을 완료해야 비밀번호를 재설정할 수 있습니다." );
214+ throw new IllegalArgumentException (ERR_EMAIL_VERIFICATION_REQUIRED );
165215 }
166216
167217 boolean redisVerified = emailAuthService .isEmailVerified (loginId );
168218 if (!redisVerified ) {
169- throw new IllegalArgumentException ("이메일 인증을 완료해야 비밀번호를 재설정할 수 있습니다." );
219+ throw new IllegalArgumentException (ERR_EMAIL_VERIFICATION_REQUIRED );
170220 }
171221
172222 String encodedPassword = passwordEncoder .encode (newPassword );
@@ -184,6 +234,10 @@ public String extractLoginIdFromToken(String token) {
184234
185235 @ Transactional
186236 public MemberResponse oauth2LoginTest (OAuth2LoginTestRequest request , HttpServletResponse response ) {
237+ if (oauth2MemberRepository == null ) {
238+ throw new IllegalStateException ("OAuth2 기능이 비활성화되어 있습니다." );
239+ }
240+
187241 // 기존 OAuth2 회원 조회
188242 OAuth2Member oauth2Member = oauth2MemberRepository .findByLoginId (request .getEmail ()).orElse (null );
189243
@@ -212,7 +266,7 @@ public MemberResponse oauth2LoginTest(OAuth2LoginTestRequest request, HttpServle
212266
213267 private void validateDuplicateLoginId (String loginId ) {
214268 if (memberRepository .existsByLoginId (loginId )) {
215- throw new IllegalArgumentException ("이미 존재하는 이메일입니다." );
269+ throw new IllegalArgumentException (ERR_DUPLICATE_EMAIL );
216270 }
217271 }
218272}
0 commit comments