[스프링/Spring] JWT 인증 구현하기 (1) - JWT 토큰 기본 설정과 Provider 구현

dongbrown·2024년 10월 20일

Spring

목록 보기
11/23

Spring Boot 프로젝트에서 JWT(Json Web Token)를 이용한 인증 시스템을 구현하는 방법에 대해 알아보겠습니다. 특히 이번 포스트에서는 JWT 토큰 생성과 검증을 담당하는 Provider 클래스 구현에 초점을 맞추어 설명하겠습니다.

JWT란?

JWT는 JSON Web Token의 약자로, 당사자 간에 정보를 JSON 객체로 안전하게 전송하기 위한 독립적인 방법을 정의하는 개방형 표준(RFC 7519)입니다. 이 정보는 디지털 서명이 되어 있으므로 신뢰할 수 있습니다.

1. 의존성 추가

먼저 build.gradle에 필요한 의존성을 추가합니다.

dependencies {
    implementation 'io.jsonwebtoken:jjwt-api:0.11.5'
    runtimeOnly 'io.jsonwebtoken:jjwt-impl:0.11.5'
    runtimeOnly 'io.jsonwebtoken:jjwt-jackson:0.11.5'
}

2. JwtTokenProvider 구현

JWT 토큰의 생성과 검증을 담당하는 Provider 클래스를 구현합니다.

@Slf4j
@Component
public class JwtTokenProvider {
    private Key key;
    
    @Value("${jwt.token-validity-in-milliseconds}")
    private long tokenValidityInMilliseconds;

    @PostConstruct
    protected void init() {
        // HS512 알고리즘용 키 자동 생성
        this.key = Keys.secretKeyFor(SignatureAlgorithm.HS512);
        log.info("JWT secret key successfully generated for HS512");
    }

2.1 토큰 생성 메서드

Access Token과 Refresh Token을 생성하는 메서드를 구현합니다.

public String createAccessToken(String id, Long memberNo, String name, MemberRole role) {
    return createToken(id, memberNo, name, role, tokenValidityInMilliseconds);
}

public String createRefreshToken(String id, Long memberNo, String name, MemberRole role) {
    return createToken(id, memberNo, name, role, tokenValidityInMilliseconds * 2);
}

private String createToken(String id, Long memberNo, String name, MemberRole role, long validityInMilliseconds) {
    Claims claims = Jwts.claims().setSubject(id);
    claims.put("memberNo", memberNo);
    claims.put("name", name);
    claims.put("role", role.name());

    Date now = new Date();
    Date validity = new Date(now.getTime() + validityInMilliseconds);

    return Jwts.builder()
            .setClaims(claims)
            .setIssuedAt(now)
            .setExpiration(validity)
            .signWith(key, SignatureAlgorithm.HS512)
            .compact();
}

2.2 토큰 검증 및 정보 추출

토큰의 유효성을 검증하고 필요한 정보를 추출하는 메서드들을 구현합니다.

public boolean validateToken(String token) {
    try {
        Jwts.parserBuilder()
                .setSigningKey(key)
                .build()
                .parseClaimsJws(token);
        return true;
    } catch (SecurityException | MalformedJwtException e) {
        log.warn("잘못된 JWT 서명입니다.");
    } catch (ExpiredJwtException e) {
        log.warn("만료된 JWT 토큰입니다.");
    } catch (UnsupportedJwtException e) {
        log.warn("지원되지 않는 JWT 토큰입니다.");
    } catch (IllegalArgumentException e) {
        log.warn("JWT 토큰이 잘못되었습니다.");
    }
    return false;
}

public String getIdFromToken(String token) {
    try {
        return parseClaims(token).getSubject();
    } catch (ExpiredJwtException e) {
        return e.getClaims().getSubject();
    }
}

3. 주요 특징 및 장점

  1. 보안성: HS512 알고리즘을 사용하여 토큰을 암호화합니다.
  2. 유연성: Access Token과 Refresh Token을 별도로 관리할 수 있습니다.
  3. 에러 처리: 다양한 예외 상황에 대한 처리가 구현되어 있습니다.
  4. 로깅: 주요 동작에 대한 로그가 기록됩니다.

4. application.yml 설정

jwt:
  token-validity-in-milliseconds: 3600000  # 1시간

참고 자료

0개의 댓글