JWT를 모르시는 분들은 지난 포스트 ()를 간단하게 읽고 와주세요!
JWT는 Header, Payload, Signature
3가지로 나뉩니다.
- Header는 토큰의 타입과 Signature에 사용된 서명 알고리즘을 정의합니다.
- Payload는 Registered, Public, Private 3가지 클레임으로 나뉩니다. 각각은 여러 정보들을 담고 있습니다.
- Signature는 Base64Url로 인코딩된 헤더, 페이로드를 합쳐 SecretKey로 서명된 값을 저장합니다.
이번 포스트에서는 Spring Boot에서 로그인을 위한 JWT를 발급하는 방법에 대해서 살펴보도록 하겠습니다.
Dependency
저는 https://github.com/jwtk/jjwt를 사용하여 JWT를 발급하였습니다.
MAVEN : https://mvnrepository.com/artifact/io.jsonwebtoken/jjwt/0.9.1
상수 값
먼저 상수값을 선언해줍니다.
@Value(value = "${springboot.jwt.secret}")
private String secretKey;
// 토큰의 유효 기간 (1시간)
private final long tokenValidMillisecond = 1000L * 60 * 60;
application.yml에 정의되어 있는 springboot.jwt.secret의 값을 가져와서 secretKey를 초기화 해줍니다.
해당 Secret Key는 헤더와 페이로드를 서명하는데 사용됩니다.
tokenValidMillisecond 변수는 토큰의 유효기간을 설정하는데 사용됩니다.
@PostConstruct
protected void init(
){
logger.info("[JwtTokenProvider] init, secretKey 초기화");
secretKey = Base64.getEncoder().encodeToString(secretKey.getBytes(StandardCharsets.UTF_8));
}
@PostConstruct 어노테이션은 해당 빈이 주입된 이후 실행되는 메소드를 선언하는 어노테이션이다.
빈이 주입된 이후 값을 초기화할 수 있다.
일반 생성자는 빈이 주입되기 전에 실행된다.
Create Token
public String createToken(String userUid, List<String> roles){
logger.info("[JwtTokenProvider] createToken, 토큰 생성");
// Jwt token의 값을 넣기 위한 claims, sub 속성(제목)에 유저의 ID 삽입
Claims claims = Jwts.claims().setSubject(userUid);
// 유저의 권한 목록을 삽입
claims.put("roles", roles);
Date now = new Date();
String token = Jwts.builder()
.setClaims(claims)
// 토큰 생성 시간
.setIssuedAt(now)
// 토큰의 만료 기간을 설정
.setExpiration(new Date(now.getTime() + tokenValidMillisecond))
// 암호화 알고리즘 및 암호화에 사용되는 키 설정
.signWith(SignatureAlgorithm.HS256, secretKey)
.compact();
return token;
}
먼저 claiums 객체를 생성합니다. jjwt 의존성을 이용하여 간편하게 생성할 수 있습니다.
claims.put을 사용하여 저의 Spring boot 서버에서 사용할 역할을 담아둡니다.
Resolve Token
public String resolveToken(HttpServletRequest request){
logger.info("[JwtTokenProvider] resolveToken, 헤더에서 토큰 값 추출");
logger.info(request.getHeader("Content-Type"));
return request.getHeader("Authorization");
}
HTTP 메시지의 Authorization 헤더를 추출해서 토큰값을 가져옵니다.
Token Valid Check
public boolean validateToken(String token){
// 토큰의 유효기간이 지나지 않았는지를 체크한다.
logger.info("[JwtTokenProvider] validateToken, 토큰 유효성 체크");
try{
Jws<Claims> claims = Jwts.parser().setSigningKey(secretKey).parseClaimsJws(token);
return !claims.getBody().getExpiration().before(new Date());
} catch (Exception e){
logger.info("[JwtTokenProvider] validateToken, 토큰 유효성 체크 예외 발생" +e);
return false;
}
}
Token의 만료 기간을 체크하여 Valid를 체크합니다.
이외의 Valid는 Exception이 발생하여 토큰의 유효성의 검증이 실패합니다.
테스트로 만들어본 JWT입니다.
다음 시간에는 해당 JWT를 Spring Security와 함께 사용하여 로그인, 회원가입을 구현해보도록 하겠습니다.
'웹' 카테고리의 다른 글
Image 데이터를 RestTemplate로 통신하면서 발생한 에러 (0) | 2023.11.13 |
---|---|
Spring Cloud Eureka란? (0) | 2023.10.30 |
JWT란? (0) | 2023.10.26 |
Spring Boot 이미지 받는 방법 (0) | 2023.09.18 |
Spring Boot를 이용하여 MSA 구조 구현의 어려웠던 점 (0) | 2023.09.05 |