BackEnd/Spring Boot

Token JJWT

Raconer 2023. 4. 15. 19:51
728x90

JJWT aims to be the easiest to use and understand library for creating and verifying JSON Web Tokens (JWTs) on the JVM and Android.
JJWT는 JVM 및 Android에서 JSON 웹 토큰(JWT)을 생성하고 확인하기 위해 사용하고 이해하기 가장 쉬운 라이브러리를 목표로 합니다.

JWT 란?

JWT는 검증 가능한 간결한 형식으로 두 당사자 간에 정보를 전송하는 수단입니다.


사용 방법

방법 1. jjwt Dependency 사용

  1. Maven Repository에서 의존성 추가
import io.jsonwebtoken.*;
import org.springframework.beans.NullValueInNestedPathException;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.io.UnsupportedEncodingException;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * ClaimJwtException       : JWT 권한 claim 검사가 실패했을 때
 * ExpiredJwtException     : 유효 기간이 지난 JWT를 수신한 경우
 * MalformedJwtException   : 구조적인 문제가 있는 JWT인 경우
 * PrematureJwtException   : 접근이 허용되기 전인 JWT가 수신된 경우
 * SignatureException      : 서명 검증 실패
 * UnsupportedJwtException : 지원되지 않는 JWT 형식일 경우
 */
@Service
public class TokenService {

    @Value("${jwt.header}")
    private String AUTH_HEADER;

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

    @Value("${token.expire.time}")
    private long expireTime;

    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");

    /***
     *  1. conToken     : 토큰 생성
     *  2. chkToken     : 토큰 사용 체크
     *  3. refreshToken : 토큰 갱신
     *  4. expireToken  : 토큰 파기
     */

    public String conToken() {
        Date expire = new Date(System.currentTimeMillis() + expireTime);
        try {
            return Jwts.builder()
                    .setSubject("users/TzMUocMF4p")
                    .setExpiration(expire)
                    .claim("name", "Robert Token Man")
                    .claim("scope", "self groups/admins")
                    .signWith(SignatureAlgorithm.HS256, secret.getBytes("UTF-8"))
                    .compact();
        } catch (UnsupportedEncodingException e) {
            System.out.println("서명에 문제가 있습니다");
            return null;
        }
    }

    public String chkToken(String token) {
        try {
            Jws<Claims> claims = Jwts.parser()
                    .setSigningKey(secret.getBytes("UTF-8"))
                    .parseClaimsJws(token);
            return tokenData(claims);
        } catch (JwtException | NullPointerException | NullValueInNestedPathException e) {
            System.out.println("토큰 검사 실패: " + e.getClass().getSimpleName());
            return null;
        } catch (Exception e) {
            System.out.println("예외 발생: " + e.getMessage());
            return null;
        }
    }

    public String refreshToken(String token) {
        if (chkToken(token) == null) return "";
        Date expire = new Date(System.currentTimeMillis() + expireTime);
        return expiredChgToken(token, expire);
    }

    public String expireToken(String token) {
        Date now = new Date();
        return expiredChgToken(token, now);
    }

    private String expiredChgToken(String token, Date date) {
        try {
            final Claims claims = getAllClaimsFromToken(token);
            claims.setIssuedAt(new Date());
            return Jwts.builder()
                    .setClaims(claims)
                    .setExpiration(date)
                    .signWith(SignatureAlgorithm.HS256, secret.getBytes("UTF-8"))
                    .compact();
        } catch (Exception e) {
            return "";
        }
    }

    public String tokenData(Jws<Claims> claims) {
        return claims.getBody().toString();
    }

    public Claims getAllClaimsFromToken(String token) throws Exception {
        return Jwts.parser()
                .setSigningKey(secret.getBytes("UTF-8"))
                .parseClaimsJws(token)
                .getBody();
    }

    public String getToken(HttpServletRequest request) {
        String authHeader = request.getHeader(AUTH_HEADER);
        if (authHeader != null && authHeader.startsWith("Bearer ")) {
            return authHeader.substring(7);
        }
        return null;
    }
}

방법 2. jjwt-api (추후 작성 예정)


참고

728x90

'BackEnd > Spring Boot' 카테고리의 다른 글

Spring boot Test Case  (0) 2023.04.15
Spring Request Flow  (0) 2023.04.15
json-simple 사용  (0) 2023.04.15
HikariCP란?  (0) 2023.04.15
JDBC란?  (0) 2023.04.15