jwt(2) 활용

자이로 체펠리·2022년 1월 31일
0

jwt인증,인가

목록 보기
3/3

자바 진형의 jwt 라이브러리로는 jjwt가 있다. 이를 활용해 스프링에서 jwt토큰을 생성하고 파싱하는 방법을 코드를 통해 살펴 보겠습니다.

1. 의존성 주입

jjwt 메이븐 레포지토리
다음의 링크에서 프로젝트의 빌드도구에 따라 의존성을 주입합니다.

2. util 클래스 만들기

저는 jwt와 인증과 관련된 작업을 위해 유틸 클래스를 따로 만들어 사용했습니다.
아래 코드는 인증과정을 제외한 jwt와 관련된 메서드만을 포함하고 있습니다.


import java.util.Date;

import com.example.demo.dto.UserDto;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.MalformedJwtException;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.UnsupportedJwtException;

public class AuthUtil {
	
	   private static final String JWT_SECRET = "secretKey";

	    public static String generateAccessToken(UserDto user) {
	        Date now = new Date();
	        Date expiryDate = new Date(now.getTime() + 1000*60*30L);
	        return Jwts.builder()
	        	.setHeaderParam("type", "JWT")
	            .setSubject(user.getId()) // 사용자
	            .setIssuedAt(new Date()) // 현재 시간 기반으로 생성
	            .setExpiration(new Date(now.getTime() + 1000*60*30L)) // 만료 시간 세팅
	            .signWith(SignatureAlgorithm.HS512, JWT_SECRET) // 사용할 암호화 알고리즘, signature에 들어갈 secret 값 세팅
	            .compact();
	    }
	    
	    public static String generateRefreshToken() {
	        Date now = new Date();
	        Date expiryDate = new Date(now.getTime() + 1000*60*60*24*7L);
	        return Jwts.builder()
		        	.setHeaderParam("type", "JWT")
		            .setIssuedAt(new Date()) // 현재 시간 기반으로 생성
		            .setExpiration(expiryDate) // 만료 시간 세팅
		            .signWith(SignatureAlgorithm.HS512, JWT_SECRET) // 사용할 암호화 알고리즘, signature에 들어갈 secret 값 세팅
		            .compact();
	    }

	    public static String getUserIdFromJWT(String token){
	    	try{
	    		Claims claims = Jwts.parser()
	    				.setSigningKey(JWT_SECRET)
	    				.parseClaimsJws(token)
	    				.getBody();
	    		logger.error("get user id from access token success");
	    		return claims.getSubject();
	    	}catch(ExpiredJwtException e) {
	    		logger.error("Token can't parse because Expired JWT token");
	    	}
	    	return null;
	    }

	    // Jwt 토큰 유효성 검사
	    public static boolean validateToken(String token) throws SignatureException{
	        try {
	            Jwts.parser().setSigningKey(JWT_SECRET).parseClaimsJws(token);
	            return true;
	        } catch (MalformedJwtException e) {
	        	logger.error("Invalid JWT token");
	        } catch (ExpiredJwtException e) {
	        	logger.error("Expired JWT token");
	        } catch (UnsupportedJwtException e) {
	        	logger.error("Unsupported JWT token");
	        } catch (IllegalArgumentException e) {5개 작성하였습니다.
	        	logger.error("JWT claims string is empty.");
	        }
	        return false;
	    }
}

메서드를 4개 작성하였습니다.

코드 분석

1. access 토큰 생성 :

 	    public static String generateAccessToken(UserDto user) {
	        Date now = new Date();
	        Date expiryDate = new Date(now.getTime() + 1000*60*30L);
	        return Jwts.builder()
	        	.setHeaderParam("type", "JWT")
	            .setSubject(user.getId()) // 사용자
	            .setIssuedAt(new Date()) // 현재 시간 기반으로 생성
	            .setExpiration(new Date(now.getTime() + 1000*60*30L)) // 만료 시간 세팅
	            .signWith(SignatureAlgorithm.HS512, JWT_SECRET) // 사용할 암호화 알고리즘, signature에 들어갈 secret 값 세팅
	            .compact();
	    }

header를 설정하고, UserDto의 아이디를 payload에 채워넣고 이 두 정보와 secretKey를 통해 sigit5개 작성하였습니다.ure를 만들어줍니다.

2. refresh 토큰 생성 :

  public static String generateRefreshToken() {
	        Date now = new Date();
	        Date expiryDate = new Date(now.getTime() + 1000*60*60*24*7L);
	        return Jwts.builder()
		        	.setHeaderParam("type", "JWT")
		            .setIssuedAt(new Date()) // 현재 시간 기반으로 생성
		            .setExpiration(expiryDate) // 만료 시간 세팅
		            .signWith(SignatureAlgorithm.HS512, JWT_SECRET) // 사용할 암호화 알고리즘, signature에 들어갈 secret 값 세팅
		            .compact();
	    }

access 토큰이 만료 되었을시 사용자의 refresh토큰을 확인하여 다시 access토큰을 생성하기 위해 refresh토큰을 생성하는 메서드를 작성하였습니다.

3. 유저 정보 확인하기 :

	    public static String getUserIdFromJWT(String token){
	    	try{
	    		Claims claims = Jwts.parser()
	    				.setSigningKey(JWT_SECRET)
	    				.parseClaimsJws(token)
	    				.getBody();
	    		logger.error("get user id from access token success");
	    		return claims.getSubject();
	    	}catch(ExpiredJwtException e) {
	    		logger.error("Token can't parse because Expired JWT token");
	    	}
	    	return null;
	    }

access토큰을 파싱하여 유저 아이디를 리턴하는 메서드 입니다. jwt토큰은 만료되었을 시 예외가 발생하기 때문에 이와 관련된 예외처리 과정이 필수로 필요합니다.

4. 유효성 검사 :

	    public static boolean validateToken(String token) throws SignatureException{
	        try {
	            Jwts.parser().setSigningKey(JWT_SECRET).parseClaimsJws(token);
	            return true;
	        } catch (MalformedJwtException e) {
	        	logger.error("Invalid JWT token");
	        } catch (ExpiredJwtException e) {
	        	logger.error("Expired JWT token");
	        } catch (UnsupportedJwtException e) {
	        	logger.error("Unsupported JWT token");
	        } catch (IllegalArgumentException e) {5개 작성하였습니다.
	        	logger.error("JWT claims string is empty.");
	        }
	        return false;
	    }

jwt와 관련한 유효성 겁사를 진행합니다.

profile
"경의를 표해라. 경의를 갖고 회전의 다음 단계로 나아가는 거다…… [LESSON 4] 다."

0개의 댓글