mirror of
https://github.com/ktds-dg0501/kt-event-marketing.git
synced 2026-06-13 16:59:13 +00:00
add outer/inner sequence
This commit is contained in:
@@ -0,0 +1,129 @@
|
||||
@startuml user-로그인
|
||||
!theme mono
|
||||
|
||||
title User Service - 로그인 내부 시퀀스 (UFR-USER-020)
|
||||
|
||||
actor Client
|
||||
participant "UserController" as Controller <<API Layer>>
|
||||
participant "UserService" as Service <<Business Layer>>
|
||||
participant "AuthenticationService" as AuthService <<Business Layer>>
|
||||
participant "UserRepository" as UserRepo <<Data Layer>>
|
||||
participant "PasswordEncoder" as PwdEncoder <<Utility>>
|
||||
participant "JwtTokenProvider" as JwtProvider <<Utility>>
|
||||
participant "Redis\nCache" as Redis <<E>>
|
||||
participant "User DB\n(PostgreSQL)" as UserDB <<E>>
|
||||
|
||||
note over Controller, UserDB
|
||||
**UFR-USER-020: 로그인**
|
||||
- 입력: 전화번호, 비밀번호
|
||||
- 비밀번호 검증 (bcrypt compare)
|
||||
- JWT 토큰 발급
|
||||
- 세션 저장 (Redis)
|
||||
- 최종 로그인 시각 업데이트
|
||||
end note
|
||||
|
||||
Client -> Controller: POST /api/users/login\n(LoginRequest DTO)
|
||||
activate Controller
|
||||
|
||||
Controller -> Controller: @Valid 어노테이션 검증\n(필수 필드 확인)
|
||||
|
||||
Controller -> AuthService: authenticate(phoneNumber, password)
|
||||
activate AuthService
|
||||
|
||||
== 1단계: 사용자 조회 ==
|
||||
|
||||
AuthService -> Service: findByPhoneNumber(phoneNumber)
|
||||
activate Service
|
||||
Service -> UserRepo: findByPhoneNumber(phoneNumber)
|
||||
activate UserRepo
|
||||
UserRepo -> UserDB: SELECT user_id, password_hash,\nrole, name, email\nFROM users\nWHERE phone_number = ?
|
||||
activate UserDB
|
||||
UserDB --> UserRepo: 사용자 정보 또는 NULL
|
||||
deactivate UserDB
|
||||
UserRepo --> Service: Optional<User>
|
||||
deactivate UserRepo
|
||||
Service --> AuthService: Optional<User>
|
||||
deactivate Service
|
||||
|
||||
alt 사용자 없음
|
||||
AuthService --> Controller: throw AuthenticationFailedException\n("전화번호 또는 비밀번호를 확인해주세요")
|
||||
Controller --> Client: 401 Unauthorized\n{"error": "전화번호 또는 비밀번호를\n확인해주세요"}
|
||||
deactivate AuthService
|
||||
deactivate Controller
|
||||
|
||||
else 사용자 존재
|
||||
|
||||
== 2단계: 비밀번호 검증 ==
|
||||
|
||||
AuthService -> PwdEncoder: matches(rawPassword, passwordHash)
|
||||
activate PwdEncoder
|
||||
PwdEncoder -> PwdEncoder: bcrypt compare\n(입력 비밀번호 vs 저장된 해시)
|
||||
PwdEncoder --> AuthService: boolean (일치 여부)
|
||||
deactivate PwdEncoder
|
||||
|
||||
alt 비밀번호 불일치
|
||||
AuthService --> Controller: throw AuthenticationFailedException\n("전화번호 또는 비밀번호를 확인해주세요")
|
||||
Controller --> Client: 401 Unauthorized\n{"error": "전화번호 또는 비밀번호를\n확인해주세요"}
|
||||
deactivate AuthService
|
||||
deactivate Controller
|
||||
|
||||
else 비밀번호 일치
|
||||
|
||||
== 3단계: JWT 토큰 생성 ==
|
||||
|
||||
AuthService -> JwtProvider: generateToken(userId, role)
|
||||
activate JwtProvider
|
||||
JwtProvider -> JwtProvider: JWT 토큰 생성\n(Claims: userId, role=OWNER,\nexp=7일)
|
||||
JwtProvider --> AuthService: JWT 토큰
|
||||
deactivate JwtProvider
|
||||
|
||||
== 4단계: 세션 저장 ==
|
||||
|
||||
AuthService -> Redis: SET user:session:{token}\n(userId, role, TTL 7일)
|
||||
activate Redis
|
||||
Redis --> AuthService: 세션 저장 완료
|
||||
deactivate Redis
|
||||
|
||||
== 5단계: 최종 로그인 시각 업데이트 (비동기) ==
|
||||
|
||||
AuthService ->> Service: updateLastLoginAt(userId)
|
||||
activate Service
|
||||
note right of Service
|
||||
**비동기 처리**
|
||||
- @Async 어노테이션 사용
|
||||
- 로그인 응답 지연 방지
|
||||
end note
|
||||
Service ->> UserRepo: updateLastLoginAt(userId)
|
||||
activate UserRepo
|
||||
UserRepo ->> UserDB: UPDATE users\nSET last_login_at = NOW()\nWHERE user_id = ?
|
||||
activate UserDB
|
||||
UserDB -->> UserRepo: 업데이트 완료
|
||||
deactivate UserDB
|
||||
UserRepo -->> Service: void
|
||||
deactivate UserRepo
|
||||
Service -->> AuthService: void (비동기 완료)
|
||||
deactivate Service
|
||||
|
||||
== 6단계: 응답 반환 ==
|
||||
|
||||
AuthService -> AuthService: 응답 DTO 생성\n(LoginResponse)
|
||||
AuthService --> Controller: LoginResponse\n(token, userId, userName,\nrole, email)
|
||||
deactivate AuthService
|
||||
|
||||
Controller --> Client: 200 OK\n{"token": "jwt_token",\n"userId": 123,\n"userName": "홍길동",\n"role": "OWNER",\n"email": "hong@example.com"}
|
||||
deactivate Controller
|
||||
end
|
||||
end
|
||||
|
||||
note over Controller, UserDB
|
||||
**보안 처리**
|
||||
- 비밀번호: bcrypt compare (원본 노출 안 됨)
|
||||
- 에러 메시지: 전화번호/비밀번호 구분 없이 동일 메시지 반환 (보안 강화)
|
||||
- JWT 토큰: 7일 만료, 서버 세션과 동기화
|
||||
|
||||
**성능 최적화**
|
||||
- 최종 로그인 시각 업데이트: 비동기 처리 (@Async)
|
||||
- 응답 시간: 0.5초 목표
|
||||
end note
|
||||
|
||||
@enduml
|
||||
Reference in New Issue
Block a user