Module Xác thực Admin
Mô tả Tổng quan
Module Xác thực Admin quản lý việc xác minh danh tính và quản lý phiên làm việc cho người dùng quản trị. Nó cung cấp quyền truy cập an toàn vào các phần quản trị của ứng dụng bằng cách sử dụng xác thực Firebase, xử lý luồng đăng nhập admin và khả năng đăng nhập đại diện chuyên biệt cho phép quản trị viên đảm nhận danh tính của thành viên nhóm để hỗ trợ.
Biểu đồ Hoạt động
---
config:
theme: base
layout: dagre
flowchart:
curve: linear
htmlLabels: true
themeVariables:
edgeLabelBackground: "transparent"
---
flowchart TB
%% Main components
Client[Ứng dụng Client]
AuthController[AuthController]
AuthService(AuthService)
Firebase((Firebase Auth))
UserDB[(users)]
RoleDB[(roles)]
SessionDB[(Cookie)]
Client --- 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 Đăng nhập Admin</p>
</div>
]
Step1 --> AuthController
AuthController --- 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'>Xác thực Yêu cầu</p>
</div>
]
Step2 --> AuthService
AuthService --- 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 minh Firebase Token</p>
</div>
]
Step3 --> Firebase
Firebase --- Step4[
<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'>4</span>
<p style='margin-top: 8px'>Trả về Thông tin User</p>
</div>
]
Step4 --> AuthService
AuthService --- Step5[
<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'>5</span>
<p style='margin-top: 8px'>Tìm User</p>
</div>
]
Step5 --> UserDB
AuthService --- Step6[
<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'>6</span>
<p style='margin-top: 8px'>Kiểm tra Vai trò Admin</p>
</div>
]
Step6 --> RoleDB
AuthService --- Step7[
<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'>7</span>
<p style='margin-top: 8px'>Tạo Auth Cookies</p>
</div>
]
Step7 --> SessionDB
AuthService --- Step8[
<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'>8</span>
<p style='margin-top: 8px'>Tạo Auth Cookie</p>
</div>
]
Step8 --> AuthController
AuthController --- Step9[
<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'>9</span>
<p style='margin-top: 8px'>Trả về Phản hồi</p>
</div>
]
Step9 --> Client
%% Styling
style Client fill:#e6f3ff,stroke:#0066cc,stroke-width:2px
style AuthController fill:#e6f3ff,stroke:#0066cc,stroke-width:2px
style AuthService fill:#f0f8e6,stroke:#339933,stroke-width:2px
style Firebase fill:#fcd9d9,stroke:#cc3333,stroke-width:2px
style UserDB fill:#ffe6cc,stroke:#ff9900,stroke-width:2px
style RoleDB fill:#ffe6cc,stroke:#ff9900,stroke-width:2px
style SessionDB 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 Step4 fill:transparent,stroke:transparent,stroke-width:1px
style Step5 fill:transparent,stroke:transparent,stroke-width:1px
style Step6 fill:transparent,stroke:transparent,stroke-width:1px
style Step7 fill:transparent,stroke:transparent,stroke-width:1px
style Step8 fill:transparent,stroke:transparent,stroke-width:1px
style Step9 fill:transparent,stroke:transparent,stroke-width:1px
API: Admin Authentication API
Tài liệu Trường hợp
Trường hợp 1: Đăng nhập Admin
Mô tả
Quản trị viên đăng nhập thành công với thông tin đăng nhập hợp lệ và vai trò phù hợp.
Biểu đồ Tuần tự
sequenceDiagram
participant Admin
participant API as AuthController
participant Service as AuthService
participant Firebase
participant UserDB as users
participant AdminRoleDB as admin_roles
participant AdminRoleUserDB as admin_role_user
participant GroupDB as groups
participant GroupMemberDB as group_members
participant GroupRoleDB as group_roles
Note over Admin,API: Bước 1: Gửi Đăng nhập
Admin->>API: POST /api/v1/admin/auth/login (với firebase-token)
Note over API,Service: Bước 2: Xử lý Đăng nhập
API->>Service: login(token, data)
Note over Service,Firebase: Bước 3: Xác minh Token
Service->>Firebase: verifyIdToken(token)
Firebase-->>Service: Trả về thông tin user đã xác minh
Note over Service,UserDB: Bước 4: Tìm User
Service->>UserDB: findByUid(uid)
UserDB-->>Service: Trả về dữ liệu user
Note over Service,AdminRoleUserDB: Bước 5: Kiểm tra Vai trò Admin
Service->>AdminRoleUserDB: Kiểm tra Vai trò Admin
AdminRoleUserDB-->>Service: Trả về dữ liệu vai trò
Note over Service,GroupDB: Bước 6: Tải Dữ liệu Nhóm
Service->>GroupDB: Tải dữ liệu nhóm
GroupDB-->>Service: Trả về dữ liệu nhóm
Note over Service,GroupMemberDB: Bước 7: Tải Thành viên Nhóm
Service->>GroupMemberDB: Tải thành viên nhóm
GroupMemberDB-->>Service: Trả về dữ liệu thành viên nhóm
Note over Service,GroupRoleDB: Bước 8: Tải Vai trò Nhóm
Service->>GroupRoleDB: Tải vai trò nhóm
GroupRoleDB-->>Service: Trả về dữ liệu vai trò nhóm
Note over Service,API: Bước 9: Tạo Auth Cookie
Service->>Service: createAuthCookie(user)
Note over API,Admin: Bước 10: Trả về Phản hồi
API-->>Admin: 200 OK với dữ liệu user và cookies
Các Bước
Bước 1: Gửi Đăng nhập
- Mô tả: Admin gửi thông tin đăng nhập
- Yêu cầu:
POST /api/v1/admin/auth/login - Headers:
- firebase-token: Token từ xác thực Firebase
- Xác thực:
- Kiểm tra sự hiện diện của token
- Xác thực định dạng token
- Kiểm tra giới hạn tốc độ (5 lần/phút)
Bước 2: Xử lý Đăng nhập
- Mô tả: Controller xác thực yêu cầu và chuyển cho service
- Hành động:
- Trích xuất token từ header
- Gọi service xác thực cho quá trình đăng nhập
- Ghi log lần thử đăng nhập
Bước 3: Xác minh Token
- Mô tả: Xác minh tính xác thực của Firebase token
- Hành động:
- Gửi token đến Firebase để xác minh
- Trích xuất thông tin user từ token đã xác minh
- Xác nhận nhà cung cấp xác thực
Bước 4: Tìm User
- Mô tả: Tìm bản ghi user trong cơ sở dữ liệu
- Hành động:
- Truy vấn cơ sở dữ liệu cho user với Firebase UID khớp
- Xác minh user tồn tại và đang hoạt động
- Tải các mối quan hệ của user
Bước 5: Kiểm tra Vai trò Admin
- Mô tả: Xác minh user có quyền admin
- Hành động:
- Kiểm tra các vai trò được gán cho user
- Xác minh vai trò admin có mặt
- Xác thực quyền của vai trò
Bước 6: Tải Dữ liệu Nhóm
- Mô tả: Lấy dữ liệu liên quan đến nhóm
- Hành động:
- Truy vấn cơ sở dữ liệu cho dữ liệu nhóm
- Xác minh sự tồn tại của nhóm
- Tải các mối quan hệ của nhóm
Bước 7: Tải Thành viên Nhóm
- Mô tả: Lấy dữ liệu thành viên nhóm
- Hành động:
- Truy vấn cơ sở dữ liệu cho dữ liệu thành viên nhóm
- Xác minh sự tồn tại của thành viên nhóm
- Tải các mối quan hệ của thành viên nhóm
Bước 8: Tải Vai trò Nhóm
- Mô tả: Lấy dữ liệu vai trò nhóm
- Hành động:
- Truy vấn cơ sở dữ liệu cho dữ liệu vai trò nhóm
- Xác minh sự tồn tại của vai trò nhóm
- Tải các mối quan hệ của vai trò nhóm
Bước 9: Tạo Auth Cookie
- Mô tả: Tạo cookie phiên làm việc an toàn
- Hành động:
- Tạo token xác thực
- Tạo auth cookie với token
- Đặt cờ secure và httpOnly
- Đặt domain và path phù hợp
Bước 10: Trả về Phản hồi
- Mô tả: Gửi phản hồi thành công cho client
- Phản hồi:
- Thành công:
200 OKvới dữ liệu user - Đặt cookies trong phản hồi
- Bao gồm chi tiết user trong body phản hồi
- Thành công:
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"
boolean is_first_login "Cờ cho biết user đã hoàn thành đăng nhập lần đầu"
timestamp created_at
timestamp updated_at
}
roles {
bigint id PK
string name "Tên hiển thị vai trò"
string slug "Định danh vai trò cho quyền (duy nhất)"
timestamp created_at
timestamp updated_at
}
admin_role_user {
bigint user_id FK "Tham chiếu đến bảng users"
bigint role_id FK "Tham chiếu đến bảng roles"
timestamp created_at
timestamp updated_at
}
users ||--o{ admin_role_user : has
roles ||--o{ admin_role_user : has
Xử lý Lỗi
-
Ghi log
- Các lần đăng nhập thất bại được ghi vào log ứng dụng
- Lỗi xác minh vai trò đượ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 "Thông tin đăng nhập không chính xác." Khi thông tin đăng nhập không hợp lệ 403 "Không có quyền quản trị." Khi user thiếu vai trò admin 429 "Quá nhiều yêu cầu." Khi vượt quá giới hạn tốc độ 401 Lỗi chung với thông báo exception Khi xảy ra lỗi không mong đợi
Trường hợp 2: Đăng nhập Đại diện
Mô tả
Quản trị viên đăng nhập với tư cách đại diện của một thành viên nhóm.
Biểu đồ Tuần tự
sequenceDiagram
participant Admin
participant API as RepresentativeController
participant Service as AuthService
participant UserDB as Database
participant SessionDB as Database
Admin->>API: POST /api/v1/admin/auth/representative (với user_id)
API->>Service: loginAsRepresentative(user_id)
Service->>UserDB: findUserWithGroup(user_id)
UserDB-->>Service: Trả về dữ liệu user
Service->>SessionDB: createRepresentativeSession(admin_id, user_id)
SessionDB-->>Service: Trả về dữ liệu phiên làm việc
Service->>Service: generateRepresentativeCookie
API-->>Admin: 200 OK với cookies
Các Bước
Bước 1: Gửi Yêu cầu Đại diện
- Mô tả: Admin yêu cầu hành động với tư cách đại diện
- Yêu cầu:
POST /api/admin/auth/representative/{id} - Body Parameters:
- user_id: ID của user để đại diện
- Xác thực:
- Kiểm tra xác thực admin
- Xác minh sự tồn tại của user
- Xác thực thành viên nhóm
Bước 2: Xử lý Đăng nhập Đại diện
- Mô tả: Tạo phiên làm việc đại diện
- Hành động:
- Xác minh quyền admin
- Kiểm tra thành viên nhóm của user
- Tạo ngữ cảnh đại diện
Bước 3: Tạo Phiên làm việc Đại diện
- Mô tả: Lưu trữ dữ liệu phiên làm việc đại diện
- Hành động:
- Tạo định danh phiên làm việc
- Liên kết bản ghi admin và user
- Đặt thời gian hết hạn phiên làm việc
- Ghi log quyền truy cập đại diện
Bước 4: Tạo Cookies
- Mô tả: Tạo cookie phiên làm việc đại diện
- Hành động:
- Tạo token đại diện
- Tạo cookie an toàn
- Đặt cờ và thời gian hết hạn phù hợp
Bước 5: 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 dữ liệu user - Đặt cookie đại diện
- Bao gồm chi tiết user
- Thành công:
Ghi chú Bổ sung
- Giới hạn tốc độ: Các lần thử đăng nhập admin bị giới hạn ở 5 lần/phút cho mỗi địa chỉ IP
- Thời gian hết hạn phiên làm việc: Phiên làm việc admin hết hạn sau 8 giờ không hoạt động
- Phiên làm việc đại diện hết hạn sau 1 giờ
- Hệ thống duy trì log kiểm toán cho tất cả hành động admin và đại diện
- Cân nhắc triển khai:
- Xác thực hai yếu tố cho quyền truy cập admin
- Hạn chế truy cập dựa trên IP
- Giám sát hoạt động và cảnh báo
- Theo dõi hoạt động phiên làm việc
Tính năng Module
| Tên | Liên kết Tổng quan | Mô tả |
|---|---|---|
| Đăng nhập Admin | Đăng nhập Admin | Xác thực cho người dùng quản trị với xác minh vai trò |
| Đăng nhập Đại diện | Đăng nhập Đại diện | Xác thực để hành động thay mặt thành viên nhóm |
| Đăng xuất Admin | Đăng xuất Admin | Kết thúc phiên làm việc quản trị |
| Quản lý Mật khẩu | Quản lý Mật khẩu | Khả năng đặt lại mật khẩu quản trị |