반응형
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
...
...
}
반응형