[JWT 기능 개선] Refresh Token 생성 및 갱신 로직을 모듈화하여 JwtUtils 클래스에 메서드 추가. JwtTokenIssuanceFilter와 JwtTokenValidationFilter에서 새로운 메서드 사용으로 코드 간결화 및 유지보수성 향상.
This commit is contained in:
@@ -3,7 +3,6 @@ package com.bio.bio_backend.global.security;
|
|||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import jakarta.servlet.FilterChain;
|
import jakarta.servlet.FilterChain;
|
||||||
import jakarta.servlet.ServletException;
|
import jakarta.servlet.ServletException;
|
||||||
import jakarta.servlet.http.Cookie;
|
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
import jakarta.servlet.http.HttpServletResponse;
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
import com.bio.bio_backend.global.dto.ApiResponseDto;
|
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(),
|
String accessToken = jwtUtils.generateToken(member.getUserId(), member.getRole().getValue(),
|
||||||
Long.parseLong(Objects.requireNonNull(env.getProperty("token.expiration_time_access"))));
|
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.setRefreshToken(refreshToken);
|
||||||
member.setLastLoginAt(LocalDateTime.now());
|
member.setLastLoginAt(LocalDateTime.now());
|
||||||
|
|
||||||
memberService.updateRefreshToken(member);
|
// Refresh 토큰 쿠키 저장 - 모듈화된 메서드 사용
|
||||||
|
jwtUtils.setRefreshTokenCookie(response, refreshToken);
|
||||||
// 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")));
|
|
||||||
|
|
||||||
// JWT 토큰 전달
|
// JWT 토큰 전달
|
||||||
response.setHeader("Authorization", "Bearer " + accessToken);
|
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();
|
SecurityContextHolderStrategy contextHolder = SecurityContextHolder.getContextHolderStrategy();
|
||||||
SecurityContext context = contextHolder.createEmptyContext();
|
SecurityContext context = contextHolder.createEmptyContext();
|
||||||
|
@@ -73,6 +73,10 @@ public class JwtTokenValidationFilter extends OncePerRequestFilter {
|
|||||||
// 새로운 Access Token을 응답 헤더에 설정
|
// 새로운 Access Token을 응답 헤더에 설정
|
||||||
response.setHeader("Authorization", "Bearer " + newAccessToken);
|
response.setHeader("Authorization", "Bearer " + newAccessToken);
|
||||||
|
|
||||||
|
// Refresh Token 갱신
|
||||||
|
String newRefreshToken = jwtUtils.refreshTokens(username, role);
|
||||||
|
jwtUtils.setRefreshTokenCookie(response, newRefreshToken);
|
||||||
|
|
||||||
// 인증 정보 설정
|
// 인증 정보 설정
|
||||||
UserDetails userDetails = memberService.loadUserByUsername(username);
|
UserDetails userDetails = memberService.loadUserByUsername(username);
|
||||||
if (userDetails != null) {
|
if (userDetails != null) {
|
||||||
|
@@ -6,15 +6,19 @@ import io.jsonwebtoken.io.Decoders;
|
|||||||
import io.jsonwebtoken.security.Keys;
|
import io.jsonwebtoken.security.Keys;
|
||||||
import jakarta.servlet.http.Cookie;
|
import jakarta.servlet.http.Cookie;
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
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.service.MemberService;
|
||||||
|
import com.bio.bio_backend.domain.base.member.dto.MemberDto;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.core.env.Environment;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
import javax.crypto.SecretKey;
|
import javax.crypto.SecretKey;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
@@ -22,6 +26,7 @@ import java.util.Date;
|
|||||||
public class JwtUtils {
|
public class JwtUtils {
|
||||||
|
|
||||||
private final MemberService memberService;
|
private final MemberService memberService;
|
||||||
|
private final Environment env;
|
||||||
|
|
||||||
@Value("${token.secret_key}")
|
@Value("${token.secret_key}")
|
||||||
private String SECRET_KEY;
|
private String SECRET_KEY;
|
||||||
@@ -87,4 +92,38 @@ public class JwtUtils {
|
|||||||
}
|
}
|
||||||
return null;
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user