[Github Repository]
https://github.com/all-in-market/mvp-api-server/commit/22f8f094a5edd45f399487be55c40573861ff50d
Merge pull request #142 from all-in-market/fix/logout · all-in-market/mvp-api-server@22f8f09
Fix/logout
github.com
[AS-IS]
- 로그인 시 액세스 토큰(1시간 유효) + 리프레쉬 토큰(1주일 유효) 발급
- 리프레쉬 토큰은 UUID로 생성한 뒤, "refresh:{id}" 키로 Redis에 TTL 1주일 설정하여 저장
- [테스트] 구매자 인증 컨트롤러, 서비스 테스트 통과
- 액세스 토큰 만료 시 호출하는 "/auth/refresh" 엔드포인트에 연결된 컨트롤러 메서드 없음
- 로그아웃 시 액세스 토큰 블랙리스트 등록 + 리프레쉬 토큰 Redis에서 키 삭제 기능 없음

[TO-BE]
- 액세스 토큰 만료 시 리프레쉬 토큰으로 갱신하는 "/auth/refresh" api 구현
- buyer [x]
- seller [ ]
- admin [ ]
- 로그아웃 시 액세스 토큰 블랙리스트 등록 + 리프레쉬 토큰 Redis에서 삭제
[STEPS]
- 현행 리프레쉬 토큰 Redis 저장 방식으로는 리프레쉬 토큰으로 키에 담긴 사용자 id를 추출할 수 없음
- 키에 UUID를 포함시켜 저장하거나, 리프레쉬 토큰 저장 방식을 UUID에서 JWT로 바꿔야 함.
- 선택지: 키에 UUID를 포함시켜 저장 "refresh:{UUID}: {userId}"
- 근거: 토큰에 정보가 없어 보안성 우수, UUID 그대로 키 사용하여 간편함

- "/auth/refresh" 엔드포인트에 액세스 토큰 갱신 메서드 구현 및 테스트 코드 작성 완료

- 현재 코드에서 로그아웃 시 액세스 토큰 블랙리스트 등록하는 코드 있는지 확인
- JwtAuthenticationFilter : 요청마다 "blacklist:" + token 키로 Redis를 조회해 블랙리스트 여부를 검사하는 키는 있음
- BuyerAuthController: 없음
- SellerAuthController: 있으나 200 OK만 반환

- 로그아웃 시 액세스 토큰 블랙리스트 등록하도록 구현


- 문제 발견
- 1. 쿠키 경로 문제: 리프레시 토큰 쿠키가 path = /auth/refresh로 제한 -> /auth/logout 요청 시 브라우저가 쿠키를 포함하지 않음. refreshToken 파라미터가 null이 되어 리프레시 토큰이 삭제되지 않음.
- 2. 리프레시 토큰 로테이션 없음: /auth/refresh 호출 시 새 액세스 토큰만 발급하고 사용한 리프레시 토큰을 교체하지 않음. 토큰 탈취 시 7일간 무제한 재발급 가능
- 3. 리프레시 비즈니스 로직이 컨트롤러에 직접 작성돼 있어, 서비스로 이동 필요
- 수정
- BuyerAuthService.refresh 메서드 추가: Redis에서 userId 조회, 기존 토큰 삭제, 새 토큰 발급 및 저장, LoginResult 반환
- BuyerAuthController
- 쿠키 path("/auth/refresh) -> path("/auth" 3곳 수정 (login 응답, refresh 응답, logout 만료 쿠키)
- /auth/refresh 엔드포인트를 buyerAuthService.refresh()에 위임하도록 전면 교체
- 불필요한 RedisTemplate, JwtProvider 필드 주입 제거
- BuyerAuthServiceTest, BuyerAuthControllerTest 수정
- Seller에도 동일한 기능 적용
- 테스트 코드 작성 및 성공 확인
'Projects > [Final] Shopping Mall Project' 카테고리의 다른 글
| [트러블슈팅] CD환경에서만 ObjectMapper 빈 등록이 실패하는 이유 (0) | 2026.04.27 |
|---|---|
| [트러블슈팅] 무차별 대입 공격으로부터 로그인 방어하기 (0) | 2026.04.27 |
| [테스트] influxdb + grafana로 k6 부하 테스트 실행하기 (0) | 2026.04.23 |
| [QueryDsl] 기간별 판매 통계 조회 메서드 테스트 코드 작성 및 수정하기 (0) | 2026.04.22 |
| [트러블슈팅] TLS 비활성화 상태에서 환경별로 연결 설정 분리하기 (1) | 2026.04.22 |