[JWT 개선] MemberDto의 권한 반환 방식을 수정하고, JwtTokenIssuanceFilter 및 JwtTokenValidationFilter에서 Access Token 생성 로직을 개선하여 사용자 정보를 포함하도록 변경. JwtUtils에 사용자 세부정보 생성을 위한 메서드 추가.
This commit is contained in:
@@ -32,7 +32,7 @@ public class MemberDto implements UserDetails {
|
||||
|
||||
@Override
|
||||
public Collection<? extends GrantedAuthority> getAuthorities() {
|
||||
return Collections.singletonList(new SimpleGrantedAuthority("ROLE_USER"));
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@@ -66,7 +66,7 @@ public class JwtTokenIssuanceFilter extends UsernamePasswordAuthenticationFilter
|
||||
MemberDto member = (MemberDto) userDetails;
|
||||
|
||||
// 토큰 생성
|
||||
String accessToken = jwtUtils.createAccessToken(member.getUserId());
|
||||
String accessToken = jwtUtils.createAccessToken(member.getOid(), member.getUserId(), member.getName());
|
||||
String refreshToken = jwtUtils.createRefreshToken(member.getUserId(), httpUtils.getClientIp());
|
||||
|
||||
member.setRefreshToken(refreshToken);
|
||||
|
@@ -52,13 +52,13 @@ public class JwtTokenValidationFilter extends OncePerRequestFilter {
|
||||
|
||||
log.debug("JWT 토큰 검증 필터 실행 - URI: {}", request.getRequestURI());
|
||||
|
||||
String accessToken = jwtUtils.extractAccessJwtFromRequest(request);
|
||||
String accessToken = jwtUtils.extractAccessJwtFromCookie(request);
|
||||
String refreshToken = jwtUtils.extractRefreshJwtFromCookie(request);
|
||||
|
||||
// Access Token이 있고 유효한 경우
|
||||
if (accessToken != null && jwtUtils.validateAccessToken(accessToken)) {
|
||||
String username = jwtUtils.extractUsername(accessToken);
|
||||
UserDetails userDetails = memberService.loadUserByUsername(username);
|
||||
UserDetails userDetails = jwtUtils.createUserDetailsFromToken(accessToken);
|
||||
|
||||
if (userDetails != null) {
|
||||
UsernamePasswordAuthenticationToken authentication =
|
||||
@@ -94,7 +94,11 @@ public class JwtTokenValidationFilter extends OncePerRequestFilter {
|
||||
UserDetails userDetails = memberService.loadUserByUsername(username);
|
||||
|
||||
// 새로운 Access Token 생성
|
||||
String newAccessToken = jwtUtils.createAccessToken(username);
|
||||
String newAccessToken = jwtUtils.createAccessToken(
|
||||
((MemberDto) userDetails).getOid(),
|
||||
userDetails.getUsername(),
|
||||
((MemberDto) userDetails).getName()
|
||||
);
|
||||
|
||||
// 새로운 Access Token을 쿠키에 설정
|
||||
jwtUtils.setAccessTokenCookie(response, newAccessToken);
|
||||
|
@@ -8,10 +8,12 @@ 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.security.core.userdetails.UserDetails;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.crypto.SecretKey;
|
||||
@@ -44,6 +46,18 @@ public class JwtUtils {
|
||||
.compact();
|
||||
}
|
||||
|
||||
// Token 생성 (사용자 정보 포함)
|
||||
public String generateToken(Long oid, String username, String name, long expirationTime) {
|
||||
return Jwts.builder()
|
||||
.subject(username)
|
||||
.claim("oid", oid)
|
||||
.claim("name", name)
|
||||
.issuedAt(new Date(System.currentTimeMillis()))
|
||||
.expiration(new Date(System.currentTimeMillis() + expirationTime))
|
||||
.signWith(getSigningKey())
|
||||
.compact();
|
||||
}
|
||||
|
||||
// Token 생성(IP 정보 포함)
|
||||
public String generateToken(String username, String clientIp, long expirationTime) {
|
||||
return Jwts.builder()
|
||||
@@ -56,11 +70,12 @@ public class JwtUtils {
|
||||
}
|
||||
|
||||
// Access Token 생성
|
||||
public String createAccessToken(String username) {
|
||||
public String createAccessToken(Long oid, String username, String name) {
|
||||
long expirationTime = Long.parseLong(Objects.requireNonNull(env.getProperty("token.expiration_time_access")));
|
||||
return generateToken(username, expirationTime);
|
||||
return generateToken(oid, username, name, expirationTime);
|
||||
}
|
||||
|
||||
|
||||
// Refresh Token 생성 시 IP 정보 포함
|
||||
public String createRefreshToken(String username, String clientIp) {
|
||||
long expirationTime = Long.parseLong(Objects.requireNonNull(env.getProperty("token.expiration_time_refresh")));
|
||||
@@ -131,7 +146,7 @@ public class JwtUtils {
|
||||
}
|
||||
|
||||
// Access Token을 쿠키에서 추출
|
||||
public String extractAccessJwtFromRequest(HttpServletRequest request) {
|
||||
public String extractAccessJwtFromCookie(HttpServletRequest request) {
|
||||
if (request.getCookies() != null) {
|
||||
for (Cookie cookie : request.getCookies()) {
|
||||
if ("AccessToken".equals(cookie.getName())) {
|
||||
@@ -191,4 +206,23 @@ public class JwtUtils {
|
||||
cookie.setMaxAge(maxAge);
|
||||
response.addCookie(cookie);
|
||||
}
|
||||
|
||||
public UserDetails createUserDetailsFromToken(String accessToken) {
|
||||
try {
|
||||
Claims claims = extractAllClaims(accessToken);
|
||||
String username = claims.getSubject();
|
||||
Long oid = claims.get("oid", Long.class);
|
||||
String name = claims.get("name", String.class);
|
||||
|
||||
// 토큰에서 직접 UserDetails 생성 (DB 조회 없음)
|
||||
return MemberDto.builder()
|
||||
.oid(oid)
|
||||
.userId(username)
|
||||
.name(name)
|
||||
.build();
|
||||
} catch (Exception e) {
|
||||
log.debug("토큰에서 UserDetails 생성 실패: {}", e.getMessage());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user