본문 바로가기
Spring

[Spring] TDD 도입기(4) feat) Controller 계층 / Security provider검증

by windy7271 2024. 12. 23.
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);
}
반응형

댓글