본문으로 바로가기
반응형

Jwt에 대한 기본 개념과 구조 설명은 다음 게시글 참조.

(JWT (Json web token) : JWT 토큰의 소개와 구조 : www.leafcats.com/309)

 

Java에서 JWT 토큰을 발급하고 사용하기 위한 방법에 대한 간단한 예제 코드를 공유한다.

(기준환경 : Spring boot 2.1.2)

 

1. Dependency 추가

maven 혹은 gradle에 jjwt dependency 추가

<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt</artifactId>
    <version>0.9.1</version>
</dependency>

2. JWT 토큰 생성 및 검증 util

아래 예제에서는 서비스에 사용할 VO와 permission 정보, error정보 등을 private claim으로 token payload에 포함시켰다.

public class JwtTokenUtil {
	
    private static final String SECRET_KEY = "PRIVATE_KEY";  //TODO Key는 하드코딩 하지말고 외부에서 가져오는것을 권장
    
    public static String createToken(String subject, AccessVO accessVO, Boolean hasPermission, Errors errors) {
    	
    	long ttlMillis = (10 * 1000 * 60);
    	
        if (ttlMillis <= 0) {
            throw new RuntimeException("Expiry time must be greater than Zero : ["+ttlMillis+"] ");
        }
        SignatureAlgorithm  signatureAlgorithm= SignatureAlgorithm.HS256;
 
        byte[] secretKeyBytes = DatatypeConverter.parseBase64Binary(SECRET_KEY);
        Key signingKey = new SecretKeySpec(secretKeyBytes, signatureAlgorithm.getJcaName());
        JwtBuilder builder = Jwts.builder()
                .setSubject(subject)
                .setIssuer("leafcats.com")
                .setHeaderParam("typ", "JWT")
                .claim("hasPermission", hasPermission)
                .signWith(signatureAlgorithm, signingKey);
        
        Map<String, Object> map = new HashMap<String, Object>();
        
        //private claim으로 VO객체를 추가할 수 있음
        if(accessVO != null) {
        	builder.claim("access", accessVO);
        }
        
        if(errors != null) {
        	builder.claim("errors", errors);
        }
        
        long nowMillis = System.currentTimeMillis();
        builder.setExpiration(new Date(nowMillis + ttlMillis));
        return builder.compact();
    }
 
    public static String getSubject(String token) {
        Claims claims = Jwts.parser()
                .setSigningKey(DatatypeConverter.parseBase64Binary(SECRET_KEY))
                .parseClaimsJws(token).getBody();
        return claims.getSubject();
    }
    
    public static Claims getTokenData(String token) {
    	Claims claims = Jwts.parser()
    			.setSigningKey(DatatypeConverter.parseBase64Binary(SECRET_KEY))
    			.parseClaimsJws(token).getBody();
    	return claims;
    }
    
    public static Map<String, Object> getSubjectMap(String token) {
    	
        String subject = getSubject(token);
        Map<String, Object> map = new LinkedHashMap<String, Object>();
        map.put("result", subject);
        return map;
    }

}

 

3. 사용

 

3.1. 토큰 생성

String token = JwtTokenUtil.createToken(RequestParam.getUsername(), accessVO, hasPermission, response.getData().getErrors());

3.2. 클라이언트에서 들어온 토큰 검증

String token = registryRequestParam.getToken();

//토큰이 있으면 토큰으로 인증
if(token != null && !"".equals(token)) {
	Claims tokenData = JwtTokenUtil.getTokenData(token);
	String tmp = objectMapper.writeValueAsString(tokenData.get("access"));
	AccessVO accessVO = objectMapper.readValue(tmp, AccessVO.class);
	
	if((Boolean)tokenData.get("hasPermission")) {
		if(accessVO.getActions().contains("pull")) {
			hasPermission = true;
		}else {
...
..
		}
		
	}
}else{ //토큰 없으면 ERROR
...
...
}
반응형

 Other Contents