반응형
사용자가 로그인하고 자동으로 바로 토큰을 재발급 할 일은 없겠지만 테스트 코드를 작성하면서 문제가 있었다.
아래 메서드를 통해서 refresh 토큰이 존재할 경우는 update query를 날려주고 존재하지 않으면 새로 insert query를 날려주기 위해서 변경 감지를 사용하지 않았다.
- Refresh Token으로 Access Token을 발급시 Refresh Token도 재발급 했다.
순조롭게 테스트를 작성했는데 문제가 발생했다.
- when절 (authService에 reissueToken 메서드)
쿼리 설명
select-query 2개는 업데이트를 하기 전에 token을 통해서 유저를 조회하는 로직이 있기 때문에 발생했다.
one-to-one 관계로 refresh token ➡️ user로 단방향으로 매핑했는데 N + 1문제는 발생하지 않아서 아직 건드리지 않았다.
- 아래 쿼리에는 정상적으로 동작해서 update query가 마지막에 나가는 걸 볼 수 있다.
문제는 거의 항상 update-query가 나오지 않는것이다.
- 빨간 박스 select query 2개 다음에 update query가 나오지 않고 있다.
테스트가 깨질때도 있고 성공할 때도 있어서 토큰값이 중복되는지 테스트를 작성해봤다.
결과를 확인해보니까 distinct로 중복을 제거하니까 결과로 1개만 나오는 것이다. (토큰값이 중복된다..?)
결론부터 말하면...
token을 생성할 때 사용자 정보는 동일하기 때문에 hash값이 바뀌는 경우는 Millisecond에 의존하게 된다.
Thread를 강제로 멈추고 발급을 했을 때 정상적으로 동작하는 것을 볼 수 있었다.
100개를 1초 간격으로 생성하니까 1분 41초 정도 걸렸네요 ㅜㅜ (동작을 재대로 함)
- CPU의 속도는 흔히 1.6 GHz ~ 3.0 GHz의 속도를 가지고 있는데 이는 1초에 16억~30억 회의 연산이 실행될 수 있음을 의미한다. - 출처
ms 단위로 구분도 못하고,, 세상 좋다.
- ns 단위로 처리를 해주니까 정상적으로 통과하는 것을 볼 수 있었다.
ns 기준으로 테스트를 작성했을 때 컴퓨터 성능이 더 좋아진다면 동일한 문제가 다시 일어날 텐데 ㅜㅜ 이런 식으로 수정하는 게 맞는 건지 고민이 든다.
- 시간이 지나면 사라지는 휘발성 데이터라서 UUID로 token 값을 대체하고 redis를 사용해서 TimeToLive 속성을 이용하면 고민할 필요가 없다.(로그아웃은 redis로 관리하고 있음)
- RTR (Refresh Token Rotation) 방식을 고민하고 있어 보안 쪽으로 고민했을 때 DB로 관리하는 게 좋겠다고 생각했다. (token의 stateless 한 장점을 잃었지만)
반응형
'개발 > Spring Boot' 카테고리의 다른 글
회원 탈퇴 로직 Spring Event로 처리하기 (0) | 2024.04.06 |
---|---|
[Spring] 스레드 풀 (1) | 2024.01.29 |
Test에서 deleteAll과 deleteAllInBatch() (0) | 2023.07.18 |
UnknownEntityException 문제.. (0) | 2023.06.22 |
OAuth 2.0 GitHub 이메일 null이슈 (0) | 2023.04.08 |