728x90
반응형
이번에는 JWT prodvider 쪽을 검증 해보겠습니다.
제 provider 에서는
1. 토큰을 생성
2. 토큰을 검증
3. 만료된 토큰 검증
4. 유효하지 않은 토큰 검증
정도가 있습니다.
보통 Provider 쪽에
@Value("${jwt.secretKey}")
private String secretKey;
@Value("${jwt.expiration}")
private Long expiration;
이 코드가 있기 때문에
test 환경으로 바꿔주기 위해
@SpringBootTest(properties = "spring.profiles.active=test")
이것을 클래스 위에 선언해주시고
application-test. yml 에
jwt:
secretKey: sad
expiration: 30
처럼 작성해 주면 됩니다.
저는 PasswordEncoder 가 SecurityConfigTest.class 에 있기 때문에 필요 합니다.
@ContextConfiguration(classes = {SecurityConfigTest.class, JwtTokenProvider.class})
그러면 지금까지 상태는
@SpringBootTest(properties = "spring.profiles.active=test")
@ContextConfiguration(classes = {SecurityConfigTest.class, JwtTokenProvider.class})
class JwtTokenProviderTest {
@Autowired
private JwtTokenProvider jwtTokenProvider;
@Value("${jwt.secretKey}")
private String secretKey;
@Value("${jwt.expiration}")
private Long expiration;
@BeforeEach
void setUp() {
// secretKey와 expiration 값이 제대로 주입되었는지 확인
assertThat(secretKey).isNotNull();
assertThat(expiration).isNotNull();
}
대충 이렇게 될 것입니다.
1. 토큰 생성
@Test
@DisplayName("토큰 생성 테스트")
void testCreateAccessToken() {
// given
String memberSpecification = "test@test.com:TestUser:USER";
// when
String token = jwtTokenProvider.createAccessToken(memberSpecification);
// then
assertThat(token).isNotNull();
assertThat(token).contains(".");
}
2. 토큰 검증
@Test
@DisplayName("토큰 검증 테스트")
void testValidateTokenAndGetSubject() {
// given
String memberSpecification = "test@test.com:TestUser:USER";
String token = jwtTokenProvider.createAccessToken(memberSpecification);
// when
String subject = jwtTokenProvider.validateTokenAndGetSubject(token);
//then
assertThat(subject).isEqualTo(memberSpecification);
}
3. 만료된 토큰 검증
@Test
@DisplayName("만료된 토큰 검증 테스트")
void testExpiredToken() {
// Given
String expiredToken = Jwts.builder()
.signWith(getSigningKey())
.setSubject("expired@test.com:ExpiredUser:USER")
.setIssuedAt(new Date(System.currentTimeMillis() - 1000 * 60 * 60)) // 1시간 전
.setExpiration(new Date(System.currentTimeMillis() - 1000 * 60)) // 이미 만료됨
.compact();
// Then
assertThrows(ExpiredJwtException.class, () -> {
// When
jwtTokenProvider.validateTokenAndGetSubject(expiredToken);
});
}
4. 유효하지 않은 토큰 검증
@Test
@DisplayName("유효하지 않은 토큰 검증 테스트 - 서명 오류")
void testInvalidSignatureToken() {
// Given
String invalidToken = "eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ0ZXN0QHRlc3QuY29tOlRlc3RVc2VyOlVTRVIiLCJpYXQiOjE2ODAwMDAwMDB9.WRONG_SIGNATURE";
// Then
assertThrows(SignatureException.class, () -> {
// When
jwtTokenProvider.validateTokenAndGetSubject(invalidToken);
});
}
그리고 제 코드 에서 private 으로 선언된게 있어서 public 으로 열어주지 않고
테스트 코드 쪽으로 가져왔습니다.
private SecretKey getSigningKey() {
byte[] keyBytes = Decoders.BASE64.decode(this.secretKey);
return Keys.hmacShaKeyFor(keyBytes);
}
반응형
댓글