-
토큰 유효성 검사 관련 리팩토링회고 2024. 10. 7. 18:18
시작하며
더보기이번 프로젝트에도 인증, 인가 부분을 포함한 부분을 맡게 되었다. 이제는 개념이 많이 잡힌 것 같고, 기존 프로젝트 때 잘못했던 부분들을 파악할 수 있게 되고 있는 것 같다.
토큰 유효성 검사 시 예외 처리 부분을 잘못하고 있었다는 것을 발견했는데 그 부분에 대해서 얘기해 보겠다.
1. 문제상황


토큰에 대한 유효성 검사를 할 때 실행되는 JwtUtil 내 메서드이다. 어떤 예외가 발생하는 지 알기 위해서 주로 발생하는 예외에 대해서 try~catch문으로 감싸서 처리를 했다.
특히, 만료된 토큰인지 검증하는 메서드는 토큰 재발급시 단독으로 사용될 것 같아 분리해서 처리를 했다.
아래 로그는 만료된 토큰으로 api요청을 보냈을 때 발생하는 에러인데,
잘못 생각했던 부분은 2가지였다.

첫번째는, 내가 원하는 대로 log.error가 찍히지 않는 상황이다. 분명 ExpiredJwtException이 발생하고 있는데
위 isNotExpiredAccessTeken메서드의 catch문에서 적은 log.error가 찍히지 않고 있다. 심지어 print는 찍히고 있었다.
이유는 뒤에 getUserIdFromAccessToken(token) 메서드 실행 시, 만료된 토큰이므로 여기서 또 ExpiredJwtException이 발생하기 때문이었다. 따라서 이 부분을 수정하거나, 제거해야 했다.
방법은 3가지 정도가 떠올랐다.
1. SecurirtyContextHolder에서 id를 가져오기.
2. Jwt에서 Payload를 추출하고, 거기서 id를 가져오기.
3. id 찍는 부분을 삭제하기.
1번. Auth서비스에서 Security의존성을 가지고 있지 않으므로 불가했다.
2번. id를 로그에 저장하려면 이 방법이 가장 적합해 보였다. 다만, 이 로그를 가지고 어떤 인사이트를 얻을 수 있느냐를 생각해 봤을 때, 굳이? 라는 생각이 들었다.
성별, 연령별, 직업 등의 빅데이터를 기반으로 토큰이 만료됐을 때, api요청을 보내는 빈도를 분석할 것도 아니고, 만약 유의미한 결과가 도출됐다고 해도, 각 집단 별 토큰의 만료기간을 다르게 할 것도 아니다. 결정적으로 우리 서비스는 일단 회원가입 시 사용자를 군집화할 데이터를 받지도 않고 있다.
따라서 3번. 아예 id를 찍는 부분을 제거하기로 결정했다.

그 결과 이렇게 원하는 대로 에러 로그가 찍히게 됐다.
잘못 생각했던 부분 두번쨰는, 토큰 유효성 검사 메서드에서 만료된 토큰인지 확인하는 메서드를 분리했던 점이다.
AccessToken에서 id를 가져오는 메서드에서 알 수 있듯이, 아래 사진처럼 굳이 jwt의 Expiration에서 값을 가져와서 현재시간과 비교하지 않아도, 만료된 토큰이면 ExpiredJwtException이 발생한다.

즉, 아래 사진처럼 코드를 작성하면, 만료된 토큰인지 알 수 있는 로그만 찍히지 않을 뿐, false가 반환돼 service단에서 예외가 발생한다.

따라서 위 두 코드를 합쳐서 진행하기로 결정했다.

마치며
더보기Auth서비스에 불필요한 요청이 가지 않도록 Gateway에서 캐싱처리를 하고 api테스트 중 위와 같은 상황을 인지하여, 코드를 수정하게 되었다. 나름 잘 해결된 것 같고, 현재는 Gateway에 캐싱된 데이터가 있는데도 불구하고, Auth서비스로 verify요청이 가는 문제상황에 직면했다.. 아직 이유를 찾지는 못하였는데, 디버깅을 통하여 빨리 해결해 보겠다.
'회고' 카테고리의 다른 글
메일 발송 원리 (3) 2024.10.12 AI 검증 비즈니스 프로젝트 - 로그인 관련 트러블 슈팅 (0) 2024.08.28 AI 검증 비즈니스 프로젝트 2일차 회고(1일차 고민 해결) (0) 2024.08.23 AI 검증 비즈니스 프로젝트 1일차 회고(API, ERD, 테이블, 인프라 명세서 작성) (0) 2024.08.22