mirror of
https://github.com/ktds-dg0501/kt-event-marketing.git
synced 2025-12-06 20:06:23 +00:00
115 lines
3.6 KiB
Plaintext
115 lines
3.6 KiB
Plaintext
@startuml user-로그아웃
|
|
!theme mono
|
|
|
|
title User Service - 로그아웃 내부 시퀀스 (UFR-USER-040)
|
|
|
|
actor Client
|
|
participant "UserController" as Controller <<API Layer>>
|
|
participant "AuthenticationService" as AuthService <<Business Layer>>
|
|
participant "JwtTokenProvider" as JwtProvider <<Utility>>
|
|
participant "Redis\nCache" as Redis <<E>>
|
|
|
|
note over Controller, Redis
|
|
**UFR-USER-040: 로그아웃**
|
|
- JWT 토큰 검증
|
|
- Redis 세션 삭제
|
|
- 클라이언트 측 토큰 삭제 (프론트엔드 처리)
|
|
end note
|
|
|
|
Client -> Controller: POST /api/users/logout\nAuthorization: Bearer {JWT}
|
|
activate Controller
|
|
|
|
Controller -> Controller: @AuthenticationPrincipal\n(JWT에서 userId 추출)
|
|
|
|
Controller -> Controller: JWT 토큰 추출\n(Authorization 헤더에서)
|
|
|
|
Controller -> AuthService: logout(token, userId)
|
|
activate AuthService
|
|
|
|
== 1단계: JWT 토큰 검증 ==
|
|
|
|
AuthService -> JwtProvider: validateToken(token)
|
|
activate JwtProvider
|
|
JwtProvider -> JwtProvider: JWT 서명 검증\n(만료 시간 확인)
|
|
JwtProvider --> AuthService: boolean (유효 여부)
|
|
deactivate JwtProvider
|
|
|
|
alt JWT 토큰 무효
|
|
AuthService --> Controller: throw InvalidTokenException\n("유효하지 않은 토큰입니다")
|
|
Controller --> Client: 401 Unauthorized\n{"error": "유효하지 않은 토큰입니다"}
|
|
deactivate AuthService
|
|
deactivate Controller
|
|
|
|
else JWT 토큰 유효
|
|
|
|
== 2단계: Redis 세션 삭제 ==
|
|
|
|
AuthService -> Redis: DEL user:session:{token}
|
|
activate Redis
|
|
Redis --> AuthService: 삭제된 키 개수 (0 또는 1)
|
|
deactivate Redis
|
|
|
|
alt 세션 없음 (이미 로그아웃됨)
|
|
note right of AuthService
|
|
**멱등성 보장**
|
|
- 세션이 없어도 로그아웃 성공으로 처리
|
|
- 중복 로그아웃 요청에 안전
|
|
end note
|
|
else 세션 있음 (정상 로그아웃)
|
|
note right of AuthService
|
|
**세션 삭제 완료**
|
|
- Redis에서 세션 정보 제거
|
|
- JWT 토큰 무효화 (Blacklist 방식)
|
|
end note
|
|
end
|
|
|
|
== 3단계: JWT 토큰 Blacklist 추가 (선택적) ==
|
|
|
|
note right of AuthService
|
|
**JWT Blacklist 전략**
|
|
- 만료되지 않은 JWT 토큰을 강제로 무효화
|
|
- Redis에 토큰을 Blacklist에 추가 (TTL: 남은 만료 시간)
|
|
- API Gateway에서 Blacklist 확인
|
|
end note
|
|
|
|
AuthService -> JwtProvider: getRemainingExpiration(token)
|
|
activate JwtProvider
|
|
JwtProvider -> JwtProvider: JWT Claims에서\nexp(만료 시간) 추출\n(현재 시간과 비교)
|
|
JwtProvider --> AuthService: remainingSeconds
|
|
deactivate JwtProvider
|
|
|
|
alt 남은 만료 시간 > 0
|
|
AuthService -> Redis: SET jwt:blacklist:{token}\n"revoked" (TTL: remainingSeconds)
|
|
activate Redis
|
|
Redis --> AuthService: Blacklist 추가 완료
|
|
deactivate Redis
|
|
end
|
|
|
|
== 4단계: 응답 반환 ==
|
|
|
|
AuthService -> AuthService: 로그아웃 성공 로그 기록\n(userId, timestamp)
|
|
|
|
AuthService --> Controller: LogoutResponse\n(success: true)
|
|
deactivate AuthService
|
|
|
|
Controller --> Client: 200 OK\n{"success": true,\n"message": "안전하게 로그아웃되었습니다"}
|
|
deactivate Controller
|
|
end
|
|
|
|
note over Controller, Redis
|
|
**보안 처리**
|
|
- JWT 토큰 Blacklist: 만료 전 토큰 강제 무효화
|
|
- 멱등성 보장: 중복 로그아웃 요청에 안전
|
|
- 세션 완전 삭제: Redis에서 세션 정보 제거
|
|
|
|
**클라이언트 측 처리**
|
|
- 프론트엔드: LocalStorage 또는 Cookie에서 JWT 토큰 삭제
|
|
- 로그인 화면으로 리다이렉트
|
|
|
|
**성능 최적화**
|
|
- Redis 삭제 연산: O(1) 시간 복잡도
|
|
- 응답 시간: 0.1초 이내
|
|
end note
|
|
|
|
@enduml
|