토큰의 유효기간이 길어지면 자주 로그인할 필요가 없으니 사용자의 경험은 좋아지겠지만 그만큼 토큰 탈취에 대한 위험도는 높아진다. 일반적으로 access token은 15분~1시간 정도(짧게는 5분, 길게는 24시간까지) 설정하고 refresh token은 2주~1개월(짧게는 1일 길게는 1년까지)까지도 설정한다. 이는 어디까지나 일반적인 사항이고 보안과 사용자 경험을 고려하여 적절히 걸정한다.
JWTUtil 작성
전체적인 구성
JWTUtil은 application.properties에 선언된 속성을 사용하며 크게 토큰을 만드는 부분과 토큰을 검증하고 내용을 확인하는 부분으로 구성된다.
package com.doding.example.security.jwt;
import io.jsonwebtoken.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import javax.crypto.SecretKey;
import java.util.Date;
import java.util.Map;
@Component
@Slf4j
public class JWTUtil {
private final SecretKey key;
public JWTUtil(){
key = Jwts.SIG.HS256.key().build(); // 랜덤 salt 활용한 암호 키 생성
}
public String createAuthToken(String userId, long expireMin){
return create(userId, "authToken", expireMin);
}
private String create(String userId, String subject, long expireMin){
return null;
}
public Map<String, Object> checkAndGetClaims(String jwt){
return null;
}
}
상세구현
이제 각각의 메서드들을 구현해보자. 자세한 설명은 주석으로 대체한다.
private String create(String userId, String subject, long expireMin){
final JwtBuilder builder = Jwts.builder();
// Payload 설정 - expire, claim(key-value 쌍) 등 정보 포함
Date expireDate = new Date(System.currentTimeMillis() + 1000 * 60 * expireMin);
if (userId != null) {
builder.claim("user", userId);
}
// 직렬화 처리
builder.subject(subject).expiration(expireDate).signWith(key);
String jwt = builder.compact();
log.debug("토큰 발행: {}", jwt);
return jwt;
}