[Spring] JWT 토큰 생성과 검증하는 코드 빠르게 알아보기

2021-11-13


Photo by Surface on Unsplash

JWT 형식의 데이터를 주고받으면 따로 DB의 저장하지 않아도 해당 토큰의 값만 가지고 데이터 처리를 할 수 있다는 장점이 있다. 다만 base64로 인코딩 되어 있어 누구나 해당 토큰 정보를 확인할 수 있는데, 이러한 단점을 보안하기 위해서는 내부의 데이터는 따로 암호화 작업을 거쳐서 전달하는 것이 바람직하다. 바로 사용한 라이브러리와 예제 코드를 보자.


- 라이브러리(build.gradle)

	// https://mvnrepository.com/artifact/io.jsonwebtoken/jjwt
	implementation group: 'io.jsonwebtoken', name: 'jjwt', version: '0.9.1'

- 예제

import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.Map;

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

public class JwtUtils {

	private final String key = "암호화 키 값";
	   
	//jwt 토큰 생성
	public String createJwt(String param1, String param2) {//payload에 넣을 파라미터
    	//자신이 넣고자 하는 파라미터의 수에 따라 payload의 값은 변경된다.

        //Header 부분 설정
        Map<String, Object> headers = new HashMap<>();
        headers.put("typ", "JWT"); 
        headers.put("alg", "HS256");
		//헤더에는 jwt의 암호화 방법 정보가 들어있다.

        //payload 부분 설정
        Map<String, Object> payloads = new HashMap<>();
        payloads.put("param1", param1);
        payloads.put("param2", param2);
        //실제적인 jwt의 데이터를 담당하는 부분이다.
        
        // 토큰 Builder
        String jwt = Jwts.builder()
                .setHeader(headers) // Headers 설정
                .setClaims(payloads) // Claims 설정
                .signWith(SignatureAlgorithm.HS256, key.getBytes()) // HS256과 Key로 Sign
                .compact(); // 토큰 생성

        return jwt;
    }

    //jwt 토큰 검증
    public Map<String, Object> checkJwt(String jwt) throws UnsupportedEncodingException {
        Map<String, Object> claimMap = null;
        try {
            Claims claims = Jwts.parser()
                    .setSigningKey(key.getBytes("UTF-8")) // 키 설정
                    .parseClaimsJws(jwt) // jwt의 정보를 파싱해서 시그니처 값을 검증한다.
                    .getBody();

            claimMap = claims;
            
        } catch (ExpiredJwtException e) { // 토큰이 만료되었을 경우
            System.out.println(e);
            
        } catch (Exception e) { // 나머지 에러의 경우
            System.out.println(e);
        }
        return claimMap;
    }    
}


크게 어려울 거 없는 코드이다. 정형화된 형식이며, 사용자는 createJwt에 파라미터 정보만 대입해주면 간단히 jwt토큰을 생성할 수 있다. 추후 토큰 검증시 에는 checkJwt에서 파라미터로 넘겨진 jwt 가 자신의 키값으로 만들어진 토큰인지 시그니쳐 값을 검증하면 된다. 검증이 완료된 값은 map의 형태로 담겨 get 메서드로 jwt토큰에 담겨있는 payload의 정보를 불러올 수 있다.


메인 이미지 출처 : Photo by Surface on Unsplash