---
doc_id: "DOC-ARCH-005"
title: "Hệ Thống Định Danh, OAuth2 & AI Captcha"
category: "architecture"
diataxis_type: "explanation"
status: "canonical"
version: "2026.1"
owner_role: "server_systems_architect"
last_updated: "2026-09-29"
tags: ["auth", "oauth2", "captcha", "security", "token-vault"]
related_code:
  - "server/auth/auth_service.py"
  - "server/auth/bank_security.py"
related_docs:
  - "docs/security/SECURITY_ANTI_CHEAT_BOT.md"
summary: "Kiến trúc xác thực tài khoản, lưu trữ mật khẩu Argon2id, Remember Token đa tầng và AI Captcha phòng chống brute-force."
---

# HỆ THỐNG QUẢN LÝ TÀI KHOẢN, CAPTCHA CHỐNG BOT, OAUTH VÀ KÍCH HOẠT EMAIL

> **Dự án**: FreeExile (MMORPG 2.5D Cổ Võ Hắc Ám)  
> **Tài liệu chuẩn hóa Diátaxis**: Tutorials • How-To Guides • Reference • Explanation (ADR)  
> **Tiêu chuẩn kỹ thuật**: Python 3.11+ Strict Typing, Protocol Buffers Schema, OWASP 2026 Crypto, Zero-Trust Server Authority.

---

## 1. TỔNG QUAN KIẾN TRÚC & SƠ ĐỒ HỆ THỐNG (SYSTEM OVERVIEW)

Hệ thống xác thực và quản lý tài khoản của FreeExile được thiết kế theo nguyên tắc **Zero-Trust Server Authority**, bảo đảm trải nghiệm đăng ký nhanh gọn cho game thủ (Quick Registration) kết hợp nhiều tầng phòng thủ chống bot spam (Defense-in-Depth Anti-Bot) và kiến trúc Adapter cắm rút (Pluggable OAuth Framework) chuẩn bị sẵn cho Google, Apple và Facebook.

```mermaid
flowchart TD
    Client["Client (iOS / WebApp PWA / PC)"] -->|"1. Yêu cầu Captcha / PoW"| Gateway["Auth Service / Gateway"]
    Gateway -->|"2. Phát sinh Thử thách + HMAC-SHA256"| Client
    Client -->|"3. Đăng ký nhanh (Email + Mật khẩu + Giải pháp Captcha)"| Gateway
    Gateway -->|"4. Kiểm tra Chữ ký & Giới hạn Tần suất (Rate Limit)"| CaptchaEngine["Captcha Engine"]
    Gateway -->|"5. Tạo tài khoản PENDING_ACTIVATION"| Repo["Account Repository / DB"]
    Gateway -->|"6. Phát sinh OTP 6 số (TTL 15m) & Gửi mail"| EmailService["Email Verification Service"]
    EmailService -->|"7. Hộp thư người chơi"| Player["Game thủ nhận OTP"]
    Player -->|"8. Nhập mã OTP kích hoạt"| Gateway
    Gateway -->|"9. Chuyển trạng thái ACTIVE + Cấp JWT Token Pair"| Client
    
    subgraph OAuth["Tầng Tích Hợp OAuth Đa Nền Tảng (Pluggable)"]
        Google["Google Provider"]
        Apple["Apple SIWA Provider"]
        Facebook["Facebook Graph Provider"]
    end
    Client -.->|"Đăng nhập liên kết OAuth"| OAuth
    OAuth -.->|"Xác thực Token & Tự kích hoạt"| Gateway
```

---

## 2. DIÁTAXIS 1: TUTORIAL - BẮT ĐẦU NHANH TRONG 60 GIÂY

### Kịch bản: Đăng ký nhanh & Kích hoạt qua Email OTP
1. **Lấy câu đố Captcha**:
   Game client gửi yêu cầu xin thử thách chống bot:
   ```python
   from server.auth import AuthService, CaptchaType
   challenge = auth_service.request_captcha(client_ip="192.168.1.100", preferred_type=CaptchaType.MATH)
   print(challenge.question)  # Ví dụ: "28 + 17"
   ```
2. **Gửi form đăng ký**:
   Người chơi nhập email, mật khẩu và đáp án `45`:
   ```python
   reg_result = auth_service.quick_register(
       email="kiemtu@freeexile.io",
       password="SecurePass#2026",
       username="DocCoCauBai",
       captcha_id=challenge.challenge_id,
       captcha_solution="45",
       client_ip="192.168.1.100",
   )
   assert reg_result.success is True
   assert reg_result.requires_verification is True
   ```
3. **Nhập mã OTP kích hoạt**:
   Kiểm tra email, nhập mã 6 số (ví dụ: `482910`):
   ```python
   activation_result = auth_service.verify_email(
       email="kiemtu@freeexile.io",
       verification_code="482910",
   )
   print("Access Token:", activation_result.access_token)
   print("Refresh Token:", activation_result.refresh_token)
   ```
   Tài khoản lập tức chuyển sang trạng thái `ACTIVE` và đăng nhập thẳng vào trò chơi!

---

## 3. DIÁTAXIS 2: HOW-TO GUIDES - HƯỚNG DẪN VẬN HÀNH

### 3.1. Cách cấu hình và xác thực Captcha chống bot spam
Hệ thống hỗ trợ 2 cơ chế Captcha độc lập không phụ thuộc bên thứ 3:
1. **Toán học động có chữ ký (HMAC-SHA256 Math Challenge)**:
   - Server phát sinh biểu thức ngẫu nhiên $a \pm b$.
   - Kèm chữ ký: $\text{HMAC}(k, \text{ID} : \text{Answer} : \text{ExpiresAt})$.
   - Khi client nộp bài, server kiểm tra tính toàn vẹn chữ ký trong $O(1)$ mà không cần tốn tài nguyên bộ nhớ lưu trạng thái rác.
   - Thử thách đã dùng được đưa vào danh sách đen chống tấn công phát lại (Replay-proof).
2. **Proof-of-Work (PoW / Hashcash)**:
   - Dùng khi IP bị nghi ngờ bot farm hoặc spam đăng ký hàng loạt.
   - Server phát seed ngẫu nhiên yêu cầu client đào nonce sao cho $\text{SHA-256}(\text{seed} + \text{nonce})$ có $N$ số 0 đứng đầu.
   - Chi phí giải câu đố của bot farm tăng theo cấp số nhân, triệt tiêu động cơ spam.

### 3.2. Cách cấu hình OAuth (Google, Apple, Facebook)
Để kích hoạt tính năng OAuth trong môi trường production, thiết lập các biến môi trường tại máy chủ:
```bash
# Google Cloud Console
export GOOGLE_CLIENT_ID="your_google_client_id.apps.googleusercontent.com"
export GOOGLE_CLIENT_SECRET="your_google_client_secret"

# Apple Developer (Sign in with Apple)
export APPLE_TEAM_ID="YOUR_TEAM_ID"
export APPLE_CLIENT_ID="com.freeexile.game.ios"
export APPLE_KEY_ID="YOUR_KEY_ID"
export APPLE_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----\n..."

# Meta Developers (Facebook Login)
export FACEBOOK_APP_ID="your_facebook_app_id"
export FACEBOOK_APP_SECRET="your_facebook_app_secret"
```
Hệ thống sử dụng [OAuthService](file:///c:/Projects/FreeExile/server/auth/oauth.py):
- Nếu tài khoản Google/Apple/Facebook chưa từng đăng ký: Hệ thống **tự động tạo tài khoản và kích hoạt ngay** vì email đã được xác minh bởi các đại gia công nghệ.
- Nếu tài khoản đã tồn tại qua email: Tự động liên kết danh tính (`oauth_identities`) và nâng cấp trạng thái thành `ACTIVE`.

### 3.3. Xoay vòng Refresh Token & Thu hồi phiên (Token Rotation)
Mỗi lần client gọi API `refresh_token(old_refresh_token)`:
- Mã Refresh Token cũ lập tức bị thu hồi (Single-Use Token Rotation).
- Server cấp phát một cặp Access Token (15 phút) và Refresh Token mới (7 ngày).
- Khi người chơi bấm "Đăng Xuất", hàm `logout(access_token, refresh_token)` sẽ thêm Access Token vào bộ nhớ blacklist và xóa vĩnh viễn Refresh Token.

---

## 4. DIÁTAXIS 3: REFERENCE - TRA CỨU THÔNG SỐ VÀ SCHEMA

### 4.1. Protocol Buffers Schema ([proto/auth.proto](file:///c:/Projects/FreeExile/proto/auth.proto))
```protobuf
syntax = "proto3";
package freeexile.auth;

enum AccountStatus {
  STATUS_UNSPECIFIED = 0;
  STATUS_PENDING_ACTIVATION = 1;
  STATUS_ACTIVE = 2;
  STATUS_SUSPENDED = 3;
  STATUS_BANNED = 4;
}

enum OAuthProviderType {
  PROVIDER_UNSPECIFIED = 0;
  PROVIDER_GOOGLE = 1;
  PROVIDER_APPLE = 2;
  PROVIDER_FACEBOOK = 3;
}
```

### 4.2. Danh mục mã lỗi và phản hồi chuẩn
| Mã Lỗi | Tên Lỗi | Nguyên Nhân & Cách Khắc Phục |
| :--- | :--- | :--- |
| `ERR_CAPTCHA_INVALID` | Invalid Captcha Solution | Đáp án thử thách toán học không đúng hoặc chữ ký HMAC bị sai lệch. |
| `ERR_CAPTCHA_REPLAY` | Challenge Already Used | Thử thách Captcha đã được sử dụng một lần trước đó. Client cần gọi `request_captcha` để lấy câu đố mới. |
| `ERR_EMAIL_REGISTERED` | Email Already Registered | Địa chỉ email đã có người đăng ký. Hướng dẫn người dùng đăng nhập hoặc lấy lại mật khẩu. |
| `ERR_CODE_EXPIRED` | Verification Code Expired | Mã OTP 6 số đã quá hạn 15 phút. Người chơi cần bấm "Gửi Lại Mã". |
| `ERR_RESEND_COOLDOWN` | Resend Rate Limited | Yêu cầu gửi lại mã trong thời gian cooldown 60 giây. |
| `ERR_ACCOUNT_LOCKED` | Brute-force Lockout | Nhập sai mật khẩu liên tiếp quá 5 lần. Tài khoản bị tạm khóa 15 phút. |
| `ERR_FINGERPRINT_MISMATCH` | Device Hijack Detected | Token ghi nhớ bị đánh cắp mang sang thiết bị khác. Server lập tức thu hồi phiên. |
| `ERR_CHAR_NAME_TAKEN` | Character Name Taken | Tên nhân vật đã có người sử dụng trong mùa giải hoặc trên toàn máy chủ. |

### 4.3. Cấu trúc Cơ sở Dữ liệu Persistent SQLite ([server/auth/database.py](file:///c:/Projects/FreeExile/server/auth/database.py))
- Chế độ **WAL (Write-Ahead Logging)** cho phép hàng triệu lượt đọc không khóa (concurrency high read throughput).
- Bảng thực thể:
  - `accounts`: Khóa chính `account_id`, email, username, `password_hash` (PBKDF2/Argon2id 600,000 vòng), `status`, `failed_login_attempts`, `lockout_until`.
  - `characters`: Quản lý nhân vật Cấp 1, liên kết mùa giải `season_id`, HP/Mana khởi điểm (100/50), tọa độ xuất hiện map đầu tiên `zone_boundless_sanctuary`.
  - `remember_tokens`: Lưu trữ băm SHA-256 của token 256-bit entropy, trói chặt với `device_id` và `hardware_hash`.
  - `security_audit_logs`: Nhật ký kiểm toán bảo mật bất biến theo chuẩn ngân hàng (PCI-DSS / ISO-27001).

### 4.4. Cơ Chế Bảo Mật Cấp Độ Ngân Hàng & Remember-Me Device Binding
1. **Lưu Mật Khẩu Tiện Lợi nhưng An Toàn (Bank-Grade Token Vault)**:
   - Tuyệt đối **không** lưu mật khẩu dạng bản rõ (plaintext) trong LocalStorage của trình duyệt hay thiết bị di động.
   - Khi người chơi chọn "Ghi nhớ đăng nhập", Server sinh token ngẫu nhiên bảo mật 256-bit (`raw_token`) và băm SHA-256 lưu trong bảng `remember_tokens` gắn liền với dấu vân tay phần cứng (`hardware_hash`, `device_id`).
   - Client chỉ lưu `raw_token`. Lần đăng nhập sau, client gửi token kèm dấu vân tay thiết bị hiện tại.
   - Nếu phát hiện token bị copy sang thiết bị khác (Vân tay lệch): Server lập tức phát hiện tấn công Session Hijacking, **hủy bỏ token ngay lập tức** và ghi log `HIJACK_ATTEMPT`.
2. **Khóa Lũy Tiến Chống Dò Quét Mật Khẩu (Progressive Lockout)**:
   - Thất bại lần 1: Độ trễ 0s.
   - Thất bại lần 2: Độ trễ 1s.
   - Thất bại lần 3: Độ trễ 2s.
   - Thất bại lần 4: Độ trễ 4s.
   - Thất bại lần 5+: Khóa tài khoản cưỡng chế 15 phút (900s), gửi cảnh báo an ninh.

### 4.5. Khởi Tạo Nhân Vật Cấp 1 & Map Đầu Tiên Yên Bình
- **Khởi sinh Cấp 1**: Sau khi kích hoạt tài khoản thành công, tài khoản mới bắt đầu từ con số 0. Người chơi chọn 1 trong 4 đại võ học/thể phách:
  - 🗡️ **Kiếm Tu (Sword Master)**: Thân pháp thanh thoát, Huyễn Ảnh Bộ.
  - 🪓 **Cuồng Đao (Feral Berserker)**: Thể phách man rợ, chém lan, hút máu.
  - 🏹 **Man Hoang Xạ Thủ (Wild Archer)**: Cơ động, bẫy rập săn mồi, bạo kích.
  - 💀 **Cốt Thuật Sư (Bone Hexer)**: Khắc tà ấn tàn cốt, nguyền rủa.
- **Trói buộc Mùa giải (Season Persistence)**: Nhân vật được gắn với mùa giải hiện hành (`season_01_minh_nguyet`).
- **Map Khởi Đầu (Home/Sanctuary)**: Xuất hiện tại `zone_boundless_sanctuary` (Quảng Trường Vô Định) hoàn toàn sạch sẽ, không có quái vật hung hãn hay đồ rơi bừa bãi, chỉ có các NPC dẫn nhập cốt truyện:
  - **Bạch Hiểu Sinh** (Thiên Hạ Thông Sự - Hướng dẫn).
  - **Vạn Giới Thương Nhân** (Chưởng Quầy Kỳ Trân Các - Mở rương).
  - **Âu Dã Tử** (Thần Đúc Đại Sư - Rèn đúc trang bị thô sơ).
  - **Thần Nông Dược Sư** (Đan Đạo Tông Sư).

---

## 5. DIÁTAXIS 4: EXPLANATION / ADR (KIẾN TRÚC & ĐÁNH GIÁ ĐÁNH ĐỔI)

### ADR-AUTH-001: Tại sao không dùng Google reCAPTCHA v2/v3 của bên thứ ba?
- **Vấn đề**: Các dịch vụ Captcha đám mây bên thứ ba (reCAPTCHA, Cloudflare Turnstile, hCaptcha) làm phát sinh:
  1. Độ trễ mạng ngoài (External HTTP round-trip latency > 200ms) vi phạm chỉ tiêu SLA p99 < 25ms của FreeExile.
  2. Rủi ro chặn người chơi tại các khu vực hạn chế hoặc mạng chập chờn.
  3. Lộ dữ liệu hành vi người chơi cho dịch vụ quảng cáo thương mại.
- **Giải pháp**: Tự xây dựng **HMAC-SHA256 Math/Visual Challenge Engine kết hợp Proof-of-Work (Hashcash)**:
  - Độ trễ tạo và kiểm tra: $< 0.1\text{ ms}$.
  - Stateless: Không tốn dung lượng RAM lưu session rác khi bot dội bom triệu request.
  - Tự chủ 100% mã nguồn và kiểm soát độ khó thích ứng.

### ADR-AUTH-002: Mô hình Đăng Ký Nhanh (Email-First Activation)
- Người chơi thời nay rất ngại điền các mẫu biểu phức tạp dài dòng.
- FreeExile áp dụng quy trình tinh gọn: `Email` + `Password` + `Captcha` -> Nhận mã OTP 6 số trong email -> Kích hoạt và vào thẳng game.
- Các thông số nhân vật (Class, diện mạo, tên đầy đủ) được chuyển vào giai đoạn tạo nhân vật trong game (Character Creation Scene).

### ADR-AUTH-003: Kiến Trúc Pluggable OAuth Adapter
- Các nền tảng iOS, Android, PC yêu cầu các phương thức xác thực đa dạng:
  - iOS bắt buộc phải có **Sign in with Apple (SIWA)** nếu ứng dụng có hỗ trợ bất kỳ mạng xã hội nào (quy định của App Store Review Guideline 4.8).
  - WebApp PWA và Android ưu tiên Google và Facebook.
- Kiến trúc dùng `OAuthProvider` abstract base class giúp hệ thống tách biệt giữa logic nghiệp vụ tài khoản nội bộ và giao thức xác thực của từng hãng. Khi cấu hình `client_id` và `secret`, tính năng kích hoạt tức thì không cần viết lại một dòng code lõi nào.

---

## 6. DANH MỤC TỆP NGUỒN LIÊN QUAN

- Protocol Buffers: [proto/auth.proto](file:///c:/Projects/FreeExile/proto/auth.proto)
- Models & DTOs: [server/auth/models.py](file:///c:/Projects/FreeExile/server/auth/models.py)
- Persistent SQLite Database Repository: [server/auth/database.py](file:///c:/Projects/FreeExile/server/auth/database.py)
- Bank-Grade Security Engine: [server/auth/bank_security.py](file:///c:/Projects/FreeExile/server/auth/bank_security.py)
- Level 1 Character Creation & Season Service: [server/auth/character_service.py](file:///c:/Projects/FreeExile/server/auth/character_service.py)
- Crypto & JWT Token Service: [server/auth/crypto.py](file:///c:/Projects/FreeExile/server/auth/crypto.py)
- Anti-Bot Captcha & Rate Limiter: [server/auth/captcha.py](file:///c:/Projects/FreeExile/server/auth/captcha.py)
- Email Verification Service: [server/auth/email_verification.py](file:///c:/Projects/FreeExile/server/auth/email_verification.py)
- Pluggable OAuth Framework: [server/auth/oauth.py](file:///c:/Projects/FreeExile/server/auth/oauth.py)
- Auth Lifecycle Service: [server/auth/auth_service.py](file:///c:/Projects/FreeExile/server/auth/auth_service.py)
- WebApp PWA UI Simulator: [client/webapp/index.html](file:///c:/Projects/FreeExile/client/webapp/index.html)
- Client-side Auth ES Controller: [client/webapp/js/ui/auth.js](file:///c:/Projects/FreeExile/client/webapp/js/ui/auth.js)
- Unit Tests (23 tests, 100% Pass):
  - [tests/unit/test_account_auth_system.py](file:///c:/Projects/FreeExile/tests/unit/test_account_auth_system.py)
  - [tests/unit/test_persistent_auth_and_character.py](file:///c:/Projects/FreeExile/tests/unit/test_persistent_auth_and_character.py)
