memostack
article thumbnail
블로그를 이전하였습니다. 2023년 11월부터 https://bluemiv.github.io/에서 블로그를 운영하려고 합니다. 앞으로 해당 블로그의 댓글은 읽지 못할 수 도 있으니 양해바랍니다.
반응형

1. dependency 추가

mvnrepository.com/artifact/io.jsonwebtoken/jjwt/0.9.1

<html />
<dependencies> ... <!-- JWT --> <dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt</artifactId> <version>0.9.1</version> </dependency> ... </dependencies>

 

2. JWT 토큰 생성하기

JwtManager라는 Bean을 생성한다.

  • 공통으로 쓸것이기 때문에 IoC에 담아두고 써도 무관
<java />
import io.jsonwebtoken.Jwts; import io.jsonwebtoken.SignatureAlgorithm; import org.springframework.stereotype.Component; import java.util.Date; import java.util.HashMap; import java.util.Map; @Component public class JwtManager { private final String securityKey = "hello world"; // TODO 민감정보는 따로 분리하는 것이 좋다 private final Long expiredTime = 1000 * 60L * 60L * 3L; // 유효시간 3시간 /** * Member 정보를 담은 JWT 토큰을 생성한다. * * @param member Member 정보를 담은 객체 * @return String JWT 토큰 */ public String generateJwtToken(Member member) { Date now = new Date(); return Jwts.builder() .setSubject(member.getUsername()) // 보통 username .setHeader(createHeader()) .setClaims(createClaims(member)) // 클레임, 토큰에 포함될 정보 .setExpiration(new Date(now.getTime() + expiredTime)) // 만료일 .signWith(SignatureAlgorithm.HS256, securityKey) .compact(); } private Map<String, Object> createHeader() { Map<String, Object> header = new HashMap<>(); header.put("typ", "JWT"); header.put("alg", "HS256"); // 해시 256 사용하여 암호화 header.put("regDate", System.currentTimeMillis()); return header; } /** * 클레임(Claim)을 생성한다. * * @param member 토큰을 생성하기 위한 계정 정보를 담은 객체 * @return Map<String, Object> 클레임(Claim) */ private Map<String, Object> createClaims(Member member) { Map<String, Object> claims = new HashMap<>(); claims.put("username", member.getUsername()); // username claims.put("roles", member.getMemberRoles()); // 인가정보 return claims; } }
  • Member는 단순히 username, password, role 등의 정보를 담은 엔티티라서 생략한다.

 

3. 토큰으로부터 정보 가져오기

그리고, 토큰으로 부터 정보를 가지고 오는 코드를 작성해보자

<java />
import io.jsonwebtoken.Claims; import io.jsonwebtoken.Jwts; import io.jsonwebtoken.SignatureAlgorithm; import org.springframework.stereotype.Component; import java.util.Date; import java.util.HashMap; import java.util.Map; import java.util.Set; @Component public class JwtManager { private final String securityKey = "hello world"; //...중략... /** * Token 에서 Claim 을 가져온다. * * @param token JWT 토큰 * @return Claims 클레임 */ private Claims getClaims(String token) { return Jwts.parser().setSigningKey(securityKey).parseClaimsJws(token).getBody(); } /** * 토큰으로 부터 username 을 가져온다. * * @param token JWT 토큰 * @return String Member 의 username */ public String getUsernameFromToken(String token) { return (String) getClaims(token).get("username"); } /** * 토큰으로 부터 인가 정보를 가져온다. * * @param token JWT 토큰 * @return Set<MemberRole> role 정보를 가지고 있는 Set */ public Set<MemberRole> getMemberRoleSetFromToken(String token) { return (Set<MemberRole>) getClaims(token).get("roles"); } }

 

 

4. 기능 확인

토큰을 생성하고, 생성된 토큰으로부터 다시 정보를 가지고 온다.

<java />
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import java.time.LocalDateTime; import static org.junit.jupiter.api.Assertions.assertEquals; @DisplayName("JwtManger 테스트") class JwtManagerTest { private JwtManager jwtManager; @BeforeEach void setUp() { jwtManager = new JwtManager(); } @Test @DisplayName("토큰 생성 및 복호화 테스트") void tokenTest() { // given LocalDateTime now = LocalDateTime.now(); final Member member = Member.builder() .username("hong01") .password("1234") .name("hong") .email("hong@gmail.com") .phone("010-1234-5678") .registerAt(now) .passwordUpdatedAt(now) .isActive(true) .build(); // when // 1) 토큰 생성 final String token = jwtManager.generateJwtToken(member); // 2) 토큰으로부터 username 가져오기 String usernameFromToken = jwtManager.getUsernameFromToken(token); // then assertEquals("hong01", usernameFromToken); } }

테스트 성공

반응형
블로그를 이전하였습니다. 2023년 11월부터 https://bluemiv.github.io/에서 블로그를 운영하려고 합니다. 앞으로 해당 블로그의 댓글은 읽지 못할 수 도 있으니 양해바랍니다.
profile

memostack

@bluemiv_mm

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!