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 OK vớ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

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 OK với dữ liệu user
    • Đặt cookie đại diện
    • Bao gồm chi tiết user

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ị