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. Repository 홈페이지에서 Dependency 를 설정
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 : 시그니처 연산이 실패 하거나, JWT의 시그너처 검증이 실패한 경우
UnsupportedJwtException : 수신한 JWT의 형식이 애플리케이션에서 원하는 형식과 맞지 않은 경우
예를 들면, 암호화된 JWT를 사용하는 애플리케이션에 암호화되지 않은 JWT가 전달되는 경우에 이예외 발생
*/
/**
assert 불리언식; or assert 불리언식:수식;
ex) assert i < 0; or assert age > 0 : "나이는 음수가 될 수 없습니다:"+age;
i가 0보다 클경우 AssertionError발생
age가 0보다 작을 경우 AssertionError발생, 그때 AssertionError의 예외 메시지는 "나이는 음수가 될수 없습니다:age" 출력
따라서 assert 의 불리언 식이 false가 생겼을시 예외 발생
하단 try catch 문과 비슷하다
assert Jwts.parser().setSigningKey(key).parseClaimsJws(jws).getBody().getSubject().equals("Joe");
*/
@Service
public class TokenService {
@Value("${jwt.header}")
private String AUTH_HEADER;
@Value("${jwt.secret}")
private String secret;
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
@Value("${token.expire.time}")
private long expireTime;
/***
* 1. conToken : 토큰생성
* 2. chkToken : 토큰 사용 체크
* 3. refreshToken : 토큰 갱신(기간 연장)
* 4. expireToken : 토큰 파기(토큰 현재 시간으로 수정)
* */
/**
* 토큰 생성
**/
public String conToken() {
Date expire = new Date(new Date().getTime() + expireTime);
String jwt = "";
System.out.println(sdf.format(expire));
try {
jwt = Jwts.builder()
// 사용자 데이터
.setSubject("users/TzMUocMF4p")
.setExpiration(expire)
.claim("name", "Robert Token Man")
.claim("scope", "self groups/admins")
.signWith(
SignatureAlgorithm.HS256, // 헤더 알고리즘
secret.getBytes("UTF-8") // signature
)
.compact();
}catch (UnsupportedEncodingException e){
System.out.println("서명에 문제가 있습니다");
//e.getMessage();
return null;
}
return jwt;
}
/**
* 토큰 사용 체크
**/
public String chkToken(String token){
String jwt = token;
String userData = "";
try {
Jws<Claims> claims = Jwts.parser()
.setSigningKey(secret.getBytes("UTF-8"))
.parseClaimsJws(jwt);// 서명 오류를 구별한다.
userData = tokenData(claims);
System.out.println("Token Check Data : " + userData);
// assertEquals(scope, "self groups/admins");
}catch (ExpiredJwtException e){ // ClaimJwtException 같은 Exception
System.out.println("토큰 기간이 만료 되었습니다");
//e.getMessage();
return null;
}catch (MalformedJwtException e){
System.out.println("서명에 문제가 있습니다_3");
//e.getMessage();
return null;
}catch (PrematureJwtException e){ // ClaimJwtException 같은 Exception
System.out.println("서명에 문제가 있습니다_4");
//e.getMessage();
return null;
}catch (SignatureException e){
System.out.println("signingKey 가 다릅니다");
//e.getMessage();
return null;
}catch (UnsupportedJwtException e){
System.out.println("서명에 문제가 있습니다_6");
//e.getMessage();
return null;
}catch (NullPointerException e){
System.out.println("서명에 문제가 있습니다_7");
//e.getMessage();
return null;
}catch (NullValueInNestedPathException e){
System.out.println("서명에 문제가 있습니다_8");
//e.getMessage();
return null;
}catch (JwtException e){
System.out.println("서명에 문제가 있습니다_9");
//e.getMessage();
return null;
}catch (Exception e){
System.out.println("서명에 문제가 있습니다_10");
//e.getMessage();
return null;
}
return userData;
}
/**
* 토큰 갱신
**/
public String refreshToken(String token){
if(chkToken(token) == null){
return "";
}
Date expire = new Date(new Date().getTime() + expireTime);
System.out.println("refresh Expired" + sdf.format(expire));
String refreshToken = expiredChgToken(token, expire);
return refreshToken;
}
/**
* 토큰 파기
**/
public String expireToken(String token){
Date date = new Date();
System.out.println("expired Expired" + sdf.format(date));
String refreshToken = expiredChgToken(token, date);
return refreshToken;
}
/**
* 토큰 기간 변경
**/
private String expiredChgToken(String token, Date date){
String refreshToken = "";
try{
final Claims claims = getAllClaimsFromToken(token);
claims.setIssuedAt(new Date());
refreshToken = Jwts.builder()
.setClaims(claims)
.setExpiration(date)
.signWith(SignatureAlgorithm.HS256, secret.getBytes("UTF-8"))
.compact();
}catch (Exception e){
e.getMessage();
return "";
}
return refreshToken;
}
/**
* 토큰 상세 데이터 String 으로 변환
**/
public String tokenData(Jws<Claims> claims){
String scope = claims.getBody().toString();
return scope;
}
/**
* 토큰 상세 데이터를 Claims화
**/
public Claims getAllClaimsFromToken(String token) throws Exception{
return Jwts.parser()
.setSigningKey(secret.getBytes("UTF-8"))
.parseClaimsJws(token)
.getBody();
}
// Header에서 토큰을 가져온다.
public String getToken(HttpServletRequest request){
String returnData = "";
String authHeader = request.getHeader(AUTH_HEADER);
if ( authHeader != null && authHeader.startsWith("Bearer ")) {
returnData = authHeader.substring(7);
return returnData;
}
return null;
}
}
방법.2 jjwt-api Dependency 사용
정리 후 입력 예정
참고
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 |