Đăng xuất Admin
Mô tả Tổng quan
Tính năng Đăng xuất Admin cung cấp cách thức an toàn để kết thúc phiên làm việc quản trị. Nó đảm bảo rằng tất cả các token xác thực, cookie phiên làm việc, và dữ liệu phiên làm việc được xóa sạch một cách an toàn. Tính năng này hỗ trợ cả đăng xuất admin thông thường và đăng xuất đại diện, đảm bảo rằng không có dữ liệu nhạy cảm nào bị để lại trong hệ thống.
Biểu đồ Hoạt động
---
config:
theme: base
layout: dagre
flowchart:
curve: linear
htmlLabels: true
themeVariables:
edgeLabelBackground: "transparent"
---
flowchart TD
%% Main components
AdminUser[Admin User]
LogoutController[LogoutController]
AuthService[AuthService]
SessionDB[(Session Store)]
CookieDB[(Cookie Store)]
%% Process steps with numbering
AdminUser --- Step1[
<div style='text-align: center'>
<span style='display: inline-block; background-color: #6699cc !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>1</span>
<p style='margin-top: 8px'>Gửi Yêu cầu Đăng xuất</p>
</div>
]
Step1 --> ValidateRequest[Xác thực Yêu cầu]
ValidateRequest --- Step2[
<div style='text-align: center'>
<span style='display: inline-block; background-color: #6699cc !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>2</span>
<p style='margin-top: 8px'>Kiểm tra Phiên làm việc</p>
</div>
]
Step2 --> CheckSession[Kiểm tra Phiên làm việc Hiện tại]
CheckSession --- Step3[
<div style='text-align: center'>
<span style='display: inline-block; background-color: #6699cc !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>3</span>
<p style='margin-top: 8px'>Xác định Loại Phiên làm việc</p>
</div>
]
Step3 --> SessionType{Loại Phiên làm việc?}
SessionType --- Step4A[
<div style='text-align: center'>
<span style='display: inline-block; background-color: #6699cc !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>4A</span>
<p style='margin-top: 8px'>Admin Thông thường</p>
</div>
]
Step4A -->|Admin| AdminLogout[Đăng xuất Admin]
SessionType --- Step4B[
<div style='text-align: center'>
<span style='display: inline-block; background-color: #6699cc !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>4B</span>
<p style='margin-top: 8px'>Đại diện</p>
</div>
]
Step4B -->|Representative| RepLogout[Đăng xuất Đại diện]
AdminLogout --- Step5A[
<div style='text-align: center'>
<span style='display: inline-block; background-color: #6699cc !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>5A</span>
<p style='margin-top: 8px'>Xóa Phiên làm việc Admin</p>
</div>
]
Step5A --> ClearAdminSession[Xóa Phiên làm việc Admin]
RepLogout --- Step5B[
<div style='text-align: center'>
<span style='display: inline-block; background-color: #6699cc !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>5B</span>
<p style='margin-top: 8px'>Xóa Phiên làm việc Đại diện</p>
</div>
]
Step5B --> ClearRepSession[Xóa Phiên làm việc Đại diện]
ClearAdminSession --- Step6A[
<div style='text-align: center'>
<span style='display: inline-block; background-color: #6699cc !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>6A</span>
<p style='margin-top: 8px'>Xóa Cookie Admin</p>
</div>
]
Step6A --> ClearAdminCookie[Xóa Admin Cookie]
ClearRepSession --- Step6B[
<div style='text-align: center'>
<span style='display: inline-block; background-color: #6699cc !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>6B</span>
<p style='margin-top: 8px'>Xóa Cookie Đại diện</p>
</div>
]
Step6B --> ClearRepCookie[Xóa Representative Cookie]
ClearAdminCookie --- Step7A[
<div style='text-align: center'>
<span style='display: inline-block; background-color: #6699cc !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>7A</span>
<p style='margin-top: 8px'>Ghi log Đăng xuất</p>
</div>
]
Step7A --> LogAdminLogout[Ghi log Đăng xuất Admin]
ClearRepCookie --- Step7B[
<div style='text-align: center'>
<span style='display: inline-block; background-color: #6699cc !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>7B</span>
<p style='margin-top: 8px'>Ghi log Đăng xuất</p>
</div>
]
Step7B --> LogRepLogout[Ghi log Đăng xuất Đại diện]
LogAdminLogout --- Step8A[
<div style='text-align: center'>
<span style='display: inline-block; background-color: #6699cc !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>8A</span>
<p style='margin-top: 8px'>Trả về Phản hồi</p>
</div>
]
Step8A --> Success[Trả về Thành công]
LogRepLogout --- Step8B[
<div style='text-align: center'>
<span style='display: inline-block; background-color: #6699cc !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>8B</span>
<p style='margin-top: 8px'>Trả về Phản hồi</p>
</div>
]
Step8B --> Success
%% Styling
style AdminUser fill:#e6f3ff,stroke:#0066cc,stroke-width:2px
style LogoutController fill:#e6f3ff,stroke:#0066cc,stroke-width:2px
style AuthService fill:#f0f8e6,stroke:#339933,stroke-width:2px
style SessionDB fill:#ffe6cc,stroke:#ff9900,stroke-width:2px
style CookieDB fill:#ffe6cc,stroke:#ff9900,stroke-width:2px
style ValidateRequest fill:#e6f3ff,stroke:#0066cc,stroke-width:2px
style CheckSession fill:#f0f8e6,stroke:#339933,stroke-width:2px
style AdminLogout fill:#f0f8e6,stroke:#339933,stroke-width:2px
style RepLogout fill:#f0f8e6,stroke:#339933,stroke-width:2px
style ClearAdminSession fill:#f0f8e6,stroke:#339933,stroke-width:2px
style ClearRepSession fill:#f0f8e6,stroke:#339933,stroke-width:2px
style ClearAdminCookie fill:#f0f8e6,stroke:#339933,stroke-width:2px
style ClearRepCookie fill:#f0f8e6,stroke:#339933,stroke-width:2px
style LogAdminLogout fill:#f0f8e6,stroke:#339933,stroke-width:2px
style LogRepLogout fill:#f0f8e6,stroke:#339933,stroke-width:2px
style Success fill:#e6f3ff,stroke:#0066cc,stroke-width:2px
style SessionType fill:#ffe6cc,stroke:#ff9900,stroke-width:2px
style Step1 fill:transparent,stroke:transparent,stroke-width:1px
style Step2 fill:transparent,stroke:transparent,stroke-width:1px
style Step3 fill:transparent,stroke:transparent,stroke-width:1px
style Step4A fill:transparent,stroke:transparent,stroke-width:1px
style Step4B fill:transparent,stroke:transparent,stroke-width:1px
style Step5A fill:transparent,stroke:transparent,stroke-width:1px
style Step5B fill:transparent,stroke:transparent,stroke-width:1px
style Step6A fill:transparent,stroke:transparent,stroke-width:1px
style Step6B fill:transparent,stroke:transparent,stroke-width:1px
style Step7A fill:transparent,stroke:transparent,stroke-width:1px
style Step7B fill:transparent,stroke:transparent,stroke-width:1px
style Step8A fill:transparent,stroke:transparent,stroke-width:1px
style Step8B fill:transparent,stroke:transparent,stroke-width:1px
Tài liệu Trường hợp
Trường hợp 1: Đăng xuất Admin Thành công
Biểu đồ Tuần tự
sequenceDiagram
participant Admin
participant API as LogoutController
participant Service as AuthService
participant SessionDB as Database
participant CookieDB as Cookie Store
Note over Admin,API: Bước 1: Gửi Yêu cầu Đăng xuất
Admin->>API: GET /api/v1/admin/auth/logout
Note over API,Service: Bước 2: Xử lý Đăng xuất
API->>Service: logout()
Note over Service,Service: Bước 3: Xác định Loại Phiên làm việc
Service->>Service: determineSessionType()
Note over Service,SessionDB: Bước 4: Xóa Phiên làm việc
Service->>SessionDB: clearAdminSession()
SessionDB-->>Service: Xác nhận xóa
Note over Service,CookieDB: Bước 5: Xóa Cookie
Service->>CookieDB: clearAdminCookies()
CookieDB-->>Service: Xác nhận xóa
Note over Service,Service: Bước 6: Ghi log
Service->>Service: logLogout()
Note over API,Admin: Bước 7: Trả về Phản hồi
API-->>Admin: 200 OK với thông báo đăng xuất
Trường hợp 2: Đăng xuất Đại diện
Biểu đồ Tuần tự
sequenceDiagram
participant Admin
participant API as LogoutController
participant Service as AuthService
participant SessionDB as Database
participant CookieDB as Cookie Store
Note over Admin,API: Bước 1: Gửi Yêu cầu Đăng xuất
Admin->>API: GET /api/v1/admin/auth/logout
Note over API,Service: Bước 2: Xử lý Đăng xuất
API->>Service: logout()
Note over Service,Service: Bước 3: Xác định Loại Phiên làm việc
Service->>Service: determineSessionType()
Note over Service,SessionDB: Bước 4: Xóa Phiên làm việc Đại diện
Service->>SessionDB: clearRepresentativeSession()
SessionDB-->>Service: Xác nhận xóa
Note over Service,CookieDB: Bước 5: Xóa Cookie Đại diện
Service->>CookieDB: clearRepresentativeCookies()
CookieDB-->>Service: Xác nhận xóa
Note over Service,Service: Bước 6: Ghi log
Service->>Service: logRepresentativeLogout()
Note over API,Admin: Bước 7: Trả về Phản hồi
API-->>Admin: 200 OK với thông báo đăng xuất đại diện
Các Bước
Bước 1: Gửi Yêu cầu Đăng xuất
- Mô tả: Admin gửi yêu cầu đăng xuất
- Yêu cầu:
GET /api/v1/admin/auth/logout - Headers:
- Không cần (sử dụng cookie phiên làm việc hiện tại)
- Xác thực:
- Kiểm tra phiên làm việc hiện tại
- Xác minh quyền truy cập
Bước 2: Xử lý Đăng xuất
- Mô tả: Controller xác thực yêu cầu và chuyển cho service
- Hành động:
- Xác minh phiên làm việc hiện tại
- Gọi service xác thực cho quá trình đăng xuất
- Ghi log yêu cầu đăng xuất
Bước 3: Xác định Loại Phiên làm việc
- Mô tả: Xác định loại phiên làm việc hiện tại
- Hành động:
- Kiểm tra cookie phiên làm việc
- Xác định xem là admin thông thường hay đại diện
- Chuẩn bị quy trình đăng xuất phù hợp
Bước 4: Xóa Phiên làm việc
- Mô tả: Xóa dữ liệu phiên làm việc khỏi cơ sở dữ liệu
- Hành động:
- Xóa bản ghi phiên làm việc admin
- Hoặc xóa bản ghi phiên làm việc đại diện
- Cập nhật trạng thái phiên làm việc
Bước 5: Xóa Cookie
- Mô tả: Xóa cookie phiên làm việc khỏi trình duyệt
- Hành động:
- Xóa admin cookie
- Hoặc xóa representative cookie
- Đặt thời gian hết hạn về quá khứ
Bước 6: Ghi log
- Mô tả: Ghi lại thông tin đăng xuất
- Hành động:
- Ghi log đăng xuất admin
- Hoặc ghi log đăng xuất đại diện
- Lưu thời gian và thông tin phiên làm việc
Bước 7: Trả về Phản hồi
- Mô tả: Gửi phản hồi thành công
- Phản hồi:
- Thành công:
200 OKvới thông báo đăng xuất - Xóa cookie trong phản hồi
- Xác nhận kết thúc phiên làm việc
- Thành công:
API Endpoint
Endpoint: GET /api/v1/admin/auth/logout
Headers:
- Không cần (sử dụng cookie phiên làm việc hiện tại)
Body Parameters:
- Không có
Response:
{
"success": true,
"message": "Đăng xuất thành công",
"data": {
"logout_type": "admin", // hoặc "representative"
"logout_time": "2024-01-01T08:00:00.000000Z",
"session_cleared": true
}
}
Bảng Cơ sở Dữ liệu Liên quan & Trường
erDiagram
users {
bigint id PK
string name "Tên đầy đủ của user"
string email "Địa chỉ email của user (duy nhất)"
string uid "Firebase user ID (duy nhất)"
int status "Trạng thái tài khoản: 1: hoạt động, 0: không hoạt động"
timestamp created_at
timestamp updated_at
}
admin_sessions {
bigint id PK
bigint user_id FK "Tham chiếu đến bảng users"
string session_id "Định danh phiên làm việc duy nhất"
timestamp expires_at "Thời gian hết hạn phiên làm việc"
boolean is_active "Trạng thái hoạt động: 1: hoạt động, 0: không hoạt động"
timestamp created_at
timestamp updated_at
}
representative_sessions {
bigint id PK
bigint admin_user_id FK "Tham chiếu đến bảng users (admin)"
bigint representative_user_id FK "Tham chiếu đến bảng users (đại diện)"
string session_id "Định danh phiên làm việc duy nhất"
timestamp expires_at "Thời gian hết hạn phiên làm việc"
boolean is_active "Trạng thái hoạt động: 1: hoạt động, 0: không hoạt động"
timestamp created_at
timestamp updated_at
}
logout_logs {
bigint id PK
bigint user_id FK "Tham chiếu đến bảng users"
string session_type "Loại phiên làm việc: admin, representative"
string session_id "Định danh phiên làm việc đã đăng xuất"
timestamp logout_time "Thời gian đăng xuất"
string ip_address "Địa chỉ IP của user"
timestamp created_at
}
users ||--o{ admin_sessions : has
users ||--o{ representative_sessions : admin_creates
users ||--o{ representative_sessions : is_represented
users ||--o{ logout_logs : logs
Xử lý Lỗi
-
Ghi log
- Tất cả các yêu cầu đăng xuất được ghi vào log ứng dụng
- Lỗi xóa phiên làm việc được ghi lại
- (Tùy chọn) Gửi tin nhắn slack cho các sự kiện bảo mật
-
Chi tiết Lỗi:
Mã Trạng thái Thông báo Lỗi Mô tả 401 "Phiên làm việc không hợp lệ." Khi không có phiên làm việc hoạt động 403 "Không có quyền truy cập." Khi không có quyền đăng xuất 500 Lỗi chung với thông báo exception Khi xảy ra lỗi không mong đợi
Ghi chú Bổ sung
- Bảo mật: Tất cả các phiên làm việc được xóa sạch khi đăng xuất
- Cookie: Cookie được xóa khỏi trình duyệt với thời gian hết hạn quá khứ
- Ghi log: Tất cả các lần đăng xuất đều được ghi lại để kiểm tra bảo mật
- Phiên làm việc: Hỗ trợ cả đăng xuất admin và đại diện
- Tự động: Phiên làm việc cũng có thể hết hạn tự động sau thời gian không hoạt động
- Cân nhắc triển khai:
- Xác nhận đăng xuất trước khi xóa dữ liệu
- Gửi email thông báo đăng xuất
- Theo dõi hoạt động đăng xuất bất thường
- Tự động đăng xuất khi phát hiện hoạt động đáng ngờ