diff --git a/src/main/java/com/bio/bio_backend/global/security/JwtTokenIssuanceFilter.java b/src/main/java/com/bio/bio_backend/global/security/JwtTokenIssuanceFilter.java index 9585b3b..1ca97a4 100644 --- a/src/main/java/com/bio/bio_backend/global/security/JwtTokenIssuanceFilter.java +++ b/src/main/java/com/bio/bio_backend/global/security/JwtTokenIssuanceFilter.java @@ -3,7 +3,6 @@ package com.bio.bio_backend.global.security; import com.fasterxml.jackson.databind.ObjectMapper; import jakarta.servlet.FilterChain; import jakarta.servlet.ServletException; -import jakarta.servlet.http.Cookie; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import com.bio.bio_backend.global.dto.ApiResponseDto; @@ -76,29 +75,18 @@ public class JwtTokenIssuanceFilter extends UsernamePasswordAuthenticationFilter String accessToken = jwtUtils.generateToken(member.getUserId(), member.getRole().getValue(), Long.parseLong(Objects.requireNonNull(env.getProperty("token.expiration_time_access")))); - String refreshToken = jwtUtils.generateToken(member.getUserId(), member.getRole().getValue(), - Long.parseLong(Objects.requireNonNull(env.getProperty("token.expiration_time_refresh")))); + // 모듈화된 메서드 사용 + String refreshToken = jwtUtils.createAndSaveRefreshToken(member.getUserId(), member.getRole().getValue()); member.setRefreshToken(refreshToken); member.setLastLoginAt(LocalDateTime.now()); - memberService.updateRefreshToken(member); - - // Refresh 토큰 쿠키 저장 - Cookie refreshTokenCookie = new Cookie("RefreshToken", refreshToken); - refreshTokenCookie.setHttpOnly(true); - refreshTokenCookie.setSecure(false); - refreshTokenCookie.setPath("/"); - refreshTokenCookie.setMaxAge(Integer.parseInt(env.getProperty("token.expiration_time_refresh"))); + // Refresh 토큰 쿠키 저장 - 모듈화된 메서드 사용 + jwtUtils.setRefreshTokenCookie(response, refreshToken); // JWT 토큰 전달 response.setHeader("Authorization", "Bearer " + accessToken); - response.addHeader("Set-Cookie", - String.format("%s=%s; HttpOnly; Secure; Path=/; Max-Age=%d; SameSite=None", - refreshTokenCookie.getName(), - refreshTokenCookie.getValue(), - refreshTokenCookie.getMaxAge())); SecurityContextHolderStrategy contextHolder = SecurityContextHolder.getContextHolderStrategy(); SecurityContext context = contextHolder.createEmptyContext(); diff --git a/src/main/java/com/bio/bio_backend/global/security/JwtTokenValidationFilter.java b/src/main/java/com/bio/bio_backend/global/security/JwtTokenValidationFilter.java index 76f86a7..9464e1f 100644 --- a/src/main/java/com/bio/bio_backend/global/security/JwtTokenValidationFilter.java +++ b/src/main/java/com/bio/bio_backend/global/security/JwtTokenValidationFilter.java @@ -73,6 +73,10 @@ public class JwtTokenValidationFilter extends OncePerRequestFilter { // 새로운 Access Token을 응답 헤더에 설정 response.setHeader("Authorization", "Bearer " + newAccessToken); + // Refresh Token 갱신 + String newRefreshToken = jwtUtils.refreshTokens(username, role); + jwtUtils.setRefreshTokenCookie(response, newRefreshToken); + // 인증 정보 설정 UserDetails userDetails = memberService.loadUserByUsername(username); if (userDetails != null) { diff --git a/src/main/java/com/bio/bio_backend/global/utils/JwtUtils.java b/src/main/java/com/bio/bio_backend/global/utils/JwtUtils.java index cec8caa..c8f7897 100644 --- a/src/main/java/com/bio/bio_backend/global/utils/JwtUtils.java +++ b/src/main/java/com/bio/bio_backend/global/utils/JwtUtils.java @@ -6,15 +6,19 @@ import io.jsonwebtoken.io.Decoders; import io.jsonwebtoken.security.Keys; import jakarta.servlet.http.Cookie; import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import com.bio.bio_backend.domain.base.member.service.MemberService; +import com.bio.bio_backend.domain.base.member.dto.MemberDto; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; +import org.springframework.core.env.Environment; import org.springframework.stereotype.Component; import org.springframework.util.StringUtils; import javax.crypto.SecretKey; import java.util.Date; +import java.util.Objects; @Component @RequiredArgsConstructor @@ -22,6 +26,7 @@ import java.util.Date; public class JwtUtils { private final MemberService memberService; + private final Environment env; @Value("${token.secret_key}") private String SECRET_KEY; @@ -87,4 +92,38 @@ public class JwtUtils { } return null; } + + // Refresh Token 생성 및 DB 저장 + public String createAndSaveRefreshToken(String username, String role) { + String refreshToken = generateToken(username, role, + Long.parseLong(Objects.requireNonNull(env.getProperty("token.expiration_time_refresh")))); + + // MemberDto 객체 생성하여 updateRefreshToken 호출 + MemberDto member = new MemberDto(); + member.setUserId(username); + member.setRefreshToken(refreshToken); + memberService.updateRefreshToken(member); + + return refreshToken; + } + + // Refresh Token 갱신 (Access Token 갱신 시 함께) + public String refreshTokens(String username, String role) { + // 새로운 Refresh Token 생성 및 DB 저장 + String newRefreshToken = createAndSaveRefreshToken(username, role); + + log.info("Refresh Token 갱신 완료: {}", username); + return newRefreshToken; + } + + // Refresh Token 쿠키 설정 + public void setRefreshTokenCookie(HttpServletResponse response, String refreshToken) { + Cookie refreshTokenCookie = new Cookie("RefreshToken", refreshToken); + refreshTokenCookie.setHttpOnly(true); + refreshTokenCookie.setSecure(false); + refreshTokenCookie.setPath("/"); + refreshTokenCookie.setMaxAge(Integer.parseInt(env.getProperty("token.expiration_time_refresh"))); + + response.addCookie(refreshTokenCookie); + } }