JWT Token

ayboori·2024년 9월 3일
0

Spring

목록 보기
21/24

JWT Token의 성질

https://velog.io/@c65621/JWT-%ED%8F%90%EA%B8%B0

JWT는 불변(immutable)한 특성을 가진 토큰

  • 한 번 생성되면 내용 변경 불가
  • 토큰에 담긴 정보(헤더, 페이로드, 서명)는 생성 시 결정
    : 즉, 만료 시간 변경 불가

JWT Token 만료 / 무효화 방법

없다!

대체 로직 1 - 새로운 토큰으로 교체

사용자의 정보가 업데이트된 후, 새로운 JWT를 발급한다. 이후 클라이언트 측에서 새로운 토큰을 받아서 이전 토큰을 교체하도록 한다.

+) 레프레시 토큰 : 토큰 만료 시 새로운 토큰 발급

리프레시 토큰 : JWT와 함께 사용하는 추가적인 보안 메커니즘

액세스 토큰: 짧은 유효 기간을 가진 토큰으로, 인증이 필요한 요청에 사용됩니다.
리프레시 토큰: 상대적으로 긴 유효 기간을 가진 토큰으로, 액세스 토큰이 만료되었을 때 새로운 액세스 토큰을 발급받기 위해 사용됩니다.
리프레시 토큰의 사용 방식은 다음과 같습니다:

리프레시 토큰 관리

로그인 시: 클라이언트는 액세스 토큰과 리프레시 토큰을 모두 받는다.
액세스 토큰 만료 시: 클라이언트는 리프레시 토큰을 사용하여 새로운 액세스 토큰을 요청한다.
서버에서 리프레시 토큰 검증 및 새로운 액세스 토큰 발급: 서버는 리프레시 토큰을 검증한 후, 새로운 액세스 토큰을 발급한다.

대체 로직 2 - 토큰 blackList 구현

서버 측에서 토큰을 블랙리스트에 추가, 더 이상 유효하지 않도록 한다.

blackList : 데이터베이스를 사용하여 관리

1) BlacklistService

@Component
public class JwtBlacklistService {

    @Autowired
    private StringRedisTemplate redisTemplate;

    private static final String BLACKLIST_KEY = "jwt_blacklist";

    public void addToBlacklist(String token, long expiration) {
        redisTemplate.opsForHash().put(BLACKLIST_KEY, token, expiration);
    }

    public boolean isTokenBlacklisted(String token) {
        return redisTemplate.opsForHash().hasKey(BLACKLIST_KEY, token);
    }

    public void removeExpiredTokens() {
        // Implement token expiration cleanup logic here if needed
    }
}

2)

jwtUtil : 블랙리스트에 추가하는 로직 추가

    public void invalidateToken(String token) {
        Claims claims = Jwts.parser()
                .setSigningKey(secretKey)
                .parseClaimsJws(token)
                .getBody();

        long expiration = claims.getExpiration().getTime();
        jwtBlacklistService.addToBlacklist(token, expiration);
    }

    // 토큰 블랙리스트 체크
    public boolean isTokenBlacklisted(String token) {
        return blacklistedTokens.contains(token);
    }

service 코드에서 사용자 삭제 시 블랙리스트에 추가

   String token = requestDto.token(); // 클라이언트에서 제공된 토큰을 가져오는 방식으로 예시
    if (token != null) {
        jwtUtil.blacklistToken(token);
    }

JWT 검증 시 토큰 유효 판단

public boolean validateToken(String token) {
    // 토큰이 블랙리스트에 있으면 유효하지 않음
    if (jwtUtil.isTokenBlacklisted(token)) {
        return false;
    }

    // 여기에 JWT의 유효성 검사를 추가
    }

@AuthenticationPrincipal

@AuthenticationPrincipal

  • 컨트롤러 메서드의 매개변수로 UserDetails를 주입받아 현재 인증된 사용자의 정보를 가져온다.
  • 엔티티 내의 모든 필드를 참조할 수 있다.
  • 이 방식은 JWT가 이미 유효하다는 전제 하에 사용된다. 즉, Spring Security가 JWT를 검증하고 사용자 정보를 SecurityContext에 저장한 상태에서 작동합니다.

    별도의 토큰 검증을 수행할 필요 없다.

+) 직접적으로 토큰 검증을 수행하려면 JwtUtil 같은 클래스에서 토큰을 직접 검증해야 한다.

+) 어노테이션을 커스텀할 수 있다. https://m42-orion.tistory.com/163

profile
프로 개발자가 되기 위해 뚜벅뚜벅.. 뚜벅초

0개의 댓글