TIL

JWT(JSON Web Token) 사용하기

류정근 2024. 5. 31. 04:36
JWT이해라도해보자!!

JWT란 무엇인가?

  • JWT(JSON Web Token)는 JSON 기반의 토큰으로, 클라이언트와 서버 간의 인증 및 정보를 안전하게 교환하기 위해 사용된다.
  • JWT는 세 부분으로 구성한다
    1. 헤더(Header): 토큰 유형과 hash 알고리즘 정보를 담고 있다.
    2. 페이로드(Payload): 사용자 정보와 클레임을 포함한다.
    3. 시그니쳐(Signature): 헤더와 페이로드를 인코딩한 후 비밀 키로 생성한 서명으로, 토큰의 무결성을 보장한다.

스프링 부트에서 JWT 사용하기

1. 의존성 추가

build.gradle 파일에 JWT 라이브러리를 추가하기

    // JWT
    compileOnly group: 'io.jsonwebtoken', name: 'jjwt-api', version: '0.11.5'
    runtimeOnly group: 'io.jsonwebtoken', name: 'jjwt-impl', version: '0.11.5'
    runtimeOnly group: 'io.jsonwebtoken', name: 'jjwt-jackson', version: '0.11.5'
     Security
    implementation 'org.springframework.boot:spring-boot-starter-security'

 

2. JWT 유틸리티 클래스 작성



import com.sparta.schedule_management.entity.UserRoleEnum;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.security.Keys;
import jakarta.annotation.PostConstruct;
import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.security.Key;
import java.util.Base64;
import java.util.Date;

@Component

public class JwtUtil {

    public static final String AUTHORIZATION_HEADER = "Authorization";
    // 사용자 권한 값의 KEY
    public static final String AUTHORIZATION_KEY = "auth";
    // Token 식별자
    public static final String BEARER_PREFIX = "Bearer ";

    // 로그 설정
    public static final Logger logger = LoggerFactory.getLogger("JWT 관련 로그");

    @Value("${jwt.secret}")
    private String secret;
    private Key key;

    //생성자가 만들어진후 한번만 실행됨
//    @PostConstruct
//    public void init() {
//        byte[] bytes = Base64.getDecoder().decode(secret);
//        key = Keys.hmacShaKeyFor(bytes);
//    }


    // Access Token 만료시간 설정 (60분)
    private final long ACCESS_TOKEN_EXPIRATION = 60 * 60 * 1000L;

    // JWT 토큰 생성
    public String generateToken(String username, UserRoleEnum role) {
        Date now = new Date();
        Date expiryDate = new Date(now.getTime() + ACCESS_TOKEN_EXPIRATION);

        return BEARER_PREFIX + Jwts.builder()
                .setSubject(username)
                .claim(AUTHORIZATION_HEADER,role )//사용자 권한
                .setIssuedAt(now)
                .setExpiration(expiryDate)
                .signWith(SignatureAlgorithm.HS256, secret)
                .compact();
    }

    public void addJwtToCookie(HttpServletResponse res, String token) {

        try {
            token = URLEncoder.encode(token, "utf-8").replaceAll("\\+", "%20"); // Cookie Value 에는 공백이 불가능해서 encoding 진행

            Cookie cookie = new Cookie(AUTHORIZATION_HEADER, token); // Name-Value
            cookie.setPath("/");

            // Response 객체에 Cookie 추가
            res.addCookie(cookie);
        } catch (UnsupportedEncodingException e) {
            logger.error(e.getMessage());
        }
    }

    // JWT 토큰에서 사용자 이름 추출
    public String getUsernameFromToken(String token) {
        Claims claims = Jwts.parser()
                .setSigningKey(secret)
                .parseClaimsJws(token)
                .getBody();

        return claims.getSubject();
    }

    // JWT 토큰 유효성 검사
    public boolean validateToken(String token) {
        try {
            Jwts.parser().setSigningKey(secret).parseClaimsJws(token);
            return true;
        } catch (Exception e) {
            return false;
        }
    }
}

 

 

3. JWT 필터 작성

JWT를 이용해 요청을 인증하는 필터를 작성한다.

 

4. WebSecurityConfigurerAdapter 설정

필터를 시큐리티 설정에 추가한다.

 

작성 했던 구조...

 

 

요약

  • JWT는 클라이언트와 서버 간의 인증을 위해 사용되는 JSON 기반의 토큰이다.
  • 스프링 부트에서 JWT를 사용하려면, 의존성을 추가하고, JWT 유틸리티 클래스와 필터를 작성한 뒤, 시큐리티 설정에 필터를 추가한다.

'TIL' 카테고리의 다른 글

applicaton.properties 환경변수 설정하기  (0) 2024.06.07
Token,RefreshTokebn 만들기  (0) 2024.06.03
의존관계 주입(DI)  (0) 2024.05.27
스프링 컨테이너와 빈  (0) 2024.05.23
좋은 객체 지향 설계의 5가지 원칙(SOLID)  (0) 2024.05.22