11package org .dfbf .soundlink .domain .user .service ;
22
33import jakarta .mail .MessagingException ;
4+ import jakarta .servlet .http .Cookie ;
5+ import jakarta .servlet .http .HttpServletRequest ;
46import jakarta .servlet .http .HttpServletResponse ;
57import jakarta .transaction .Transactional ;
68import lombok .AllArgsConstructor ;
2224import org .dfbf .soundlink .global .auth .TokenProperties ;
2325import org .dfbf .soundlink .global .exception .ErrorCode ;
2426import org .dfbf .soundlink .global .exception .ResponseResult ;
25- import org .springframework .data .redis .core .RedisTemplate ;
2627import org .springframework .http .ResponseCookie ;
2728import org .springframework .security .crypto .bcrypt .BCryptPasswordEncoder ;
2829import org .springframework .stereotype .Service ;
@@ -43,9 +44,10 @@ public class UserService {
4344 private final BCryptPasswordEncoder passwordEncoder ;
4445 private final MailService mailService ;
4546 private final RedisService redisService ;
47+
4648 private final JwtProvider jwtProvider ;
4749 private final TokenProperties tokenProperties ;
48- private RedisTemplate < String , String > redisTemplate ;
50+ private final TokenService tokenService ;
4951
5052
5153 // 회원가입
@@ -194,7 +196,7 @@ public ResponseResult login(LoginReqDto loginReqDto, HttpServletResponse respons
194196 return new ResponseResult (ErrorCode .FAIL_TO_FIND_USER , "계정을 찾을 수 없습니다." );
195197 }
196198 // 비밀번호 검증(암호화 된 비밀번호 비교)
197- if (!passwordEncoder .matches (loginReqDto .password (), userRepository .findByPassword (loginReqDto .loginId ()))){
199+ if (!passwordEncoder .matches (loginReqDto .password (), userRepository .findPasswordByLoginId (loginReqDto .loginId ()))){
198200 return new ResponseResult ( ErrorCode .NOT_EQUALS_PASSWORD ,"잘못된 비밀번호 입니다." );
199201 }
200202
@@ -220,7 +222,7 @@ public ResponseResult login(LoginReqDto loginReqDto, HttpServletResponse respons
220222 }
221223
222224 //로그아웃
223- public ResponseResult logout (HttpServletResponse response ) {
225+ public ResponseResult logout (HttpServletResponse response , HttpServletRequest request ) {
224226 try {
225227 //클라이언트 - 토큰 삭제
226228 ResponseCookie refreshCookie = ResponseCookie
@@ -232,13 +234,60 @@ public ResponseResult logout(HttpServletResponse response) {
232234 .build ();
233235 response .setHeader ("Set-Cookie" , refreshCookie .toString ());//쿠키 삭제 요청
234236
235- return new ResponseResult (ErrorCode .SUCCESS );
237+ String accessToken = jwtProvider .resolveAccessToken (request ); // 요청에서 액세스 토큰 추출
238+ Long userId = jwtProvider .getUserId (accessToken ); // 액세스 토큰을 넘겨서 userId 추출
239+
240+ tokenService .deleteRefreshToken (userId );
241+
242+ return new ResponseResult (ErrorCode .SUCCESS ,"로그아웃 되었습니다." );
236243
237244 } catch (Exception e ) {
238245 return new ResponseResult (ErrorCode . INTERNAL_SERVER_ERROR ,"로그아웃 중 오류가 발생했습니다." );
239246 }
240247 }
241248
249+ //토큰 재발급
250+ public ResponseResult reissueToken (HttpServletRequest request , HttpServletResponse response ) {
251+ String accessToken = jwtProvider .resolveAccessToken (request );
252+ String refreshToken = jwtProvider .resolveRefreshToken (request );
253+
254+ // System.out.println("AccessToken: " + accessToken);
255+ // System.out.println("RefreshToken from Cookie: " + refreshToken);
256+
257+ // AccessToken과 RefreshToken이 모두 없는 경우
258+ if (accessToken == null || refreshToken == null ) {
259+ logout (response ,request );
260+ return new ResponseResult (ErrorCode .TOKEN_INVALID , "토큰이 존재하지 않거나 만료되었습니다." );
261+ }
262+
263+ // AccessToken 유효성 확인
264+ if (jwtProvider .validateToken (accessToken )) {
265+ return new ResponseResult (ErrorCode .TOKEN_NOT_EXPIRED );// 유효한 액세스 토큰: 재발급 x
266+ }
267+
268+ // RefreshToken 유효성 확인
269+ if (jwtProvider .validateToken (refreshToken )) {
270+ Long userId = jwtProvider .getUserId (refreshToken );
271+
272+ // Redis에서 리프레시 토큰 가져오기
273+ String redisRefreshToken = tokenService .getRefreshToken (userId );
274+
275+ // Redis에서 리프레시 토큰을 확인하고, 일치하면 새 액세스 토큰 발급
276+ if (redisRefreshToken != null && redisRefreshToken .equals (refreshToken )) {
277+ String newAccessToken = jwtProvider .createAccessToken (userId );
278+
279+ // System.out.println("New AccessToken: " + newAccessToken);
280+
281+ Map <String , String > responseBody = new HashMap <>();
282+ responseBody .put ("accessToken" , newAccessToken );
242283
284+ return new ResponseResult (ErrorCode .SUCCESS , responseBody );
285+ } else {
286+ return new ResponseResult (ErrorCode .TOKEN_INVALID , "리프레시 토큰이 일치하지 않습니다." );
287+ }
288+ } else {
289+ return new ResponseResult (ErrorCode .TOKEN_INVALID , "리프레시 토큰이 유효하지 않습니다." );
290+ }
291+ }
243292
244293}
0 commit comments