# DramaLing 後端帳號管理分析報告 ## 📊 總體狀況概覽 ### ✅ 已實現功能 - **用戶註冊 (`POST /api/auth/register`)** - **用戶登入 (`POST /api/auth/login`)** - **JWT Token 認證系統** - **用戶資料管理 (`GET/PUT /api/auth/profile`)** - **用戶設定管理 (`GET/PUT /api/auth/settings`)** - **認證狀態檢查 (`GET /api/auth/status`)** ### ⚠️ 安全性問題 - **開發環境中存在硬編碼測試用戶ID** - **部分控制器缺乏權限驗證** - **JWT Secret 可能使用開發預設值** --- ## 🔐 認證系統詳細分析 ### 1. 註冊系統 (`AuthController.cs:28-110`) **功能特點:** - 用戶名唯一性檢查 - Email 唯一性檢查 - BCrypt 密碼雜湊 - 自動生成 JWT Token - 完整的輸入驗證 **驗證規則:** ```csharp Username: 3-50 字符長度 Email: 標準 Email 格式驗證 Password: 最少 8 字符 ``` ### 2. 登入系統 (`AuthController.cs:112-175`) **功能特點:** - Email + 密碼認證 - BCrypt 密碼驗證 - JWT Token 生成 - 統一錯誤訊息(避免用戶名洩露) ### 3. JWT Token 系統 (`AuthController.cs:177-204`) **設定分析:** ```csharp Secret 來源優先順序: 1. 環境變數: DRAMALING_SUPABASE_JWT_SECRET 2. 環境變數: DRAMALING_JWT_SECRET 3. 預設值: "dev-secret-minimum-32-characters-long-for-jwt-signing-in-development-mode-only" Token 有效期: 7 天 包含 Claims: NameIdentifier, sub, email, username, name ``` --- ## 🛡️ 權限控制分析 ### 已實現權限保護的端點 | 控制器 | 端點 | 權限類型 | 備註 | |--------|------|----------|------| | AuthController | `/api/auth/profile` | `[Authorize]` | 用戶資料 | | AuthController | `/api/auth/settings` | `[Authorize]` | 用戶設定 | | AuthController | `/api/auth/status` | `[Authorize]` | 認證檢查 | | StatsController | 全部端點 | `[Authorize]` | 統計數據 | ### ⚠️ 缺乏權限保護的端點 | 控制器 | 權限設定 | 風險等級 | |--------|----------|----------| | FlashcardsController | `[AllowAnonymous]` | 🔴 高風險 | | AIController | 未明確設定 | 🟡 中風險 | | ImageGenerationController | 未明確設定 | 🟡 中風險 | | OptionsVocabularyTestController | 未明確設定 | 🟡 中風險 | --- ## 🚨 硬編碼用戶問題 ### 問題位置 1. **BaseController.cs:79** ```csharp return Guid.Parse("00000000-0000-0000-0000-000000000001"); ``` 2. **ImageGenerationController.cs:160** ```csharp return Guid.Parse("00000000-0000-0000-0000-000000000001"); ``` ### 觸發條件 - 開發環境 (`ASPNETCORE_ENVIRONMENT=Development`) - JWT Token 解析失敗時的 Fallback ### 風險評估 - **開發環境**: 可接受(便於測試) - **生產環境**: 🔴 高風險(繞過認證) --- ## 🔧 AuthService 核心邏輯 ### Token 驗證流程 (`AuthService.cs:56-101`) ```csharp JWT Secret 來源優先順序: 1. 環境變數: DRAMALING_SUPABASE_JWT_SECRET 2. 配置檔案: Supabase:JwtSecret 3. 無設定時返回 null(驗證失敗) 驗證參數: - ValidateIssuer: true - ValidateAudience: true - ValidateLifetime: true - ValidateIssuerSigningKey: true - ClockSkew: 5 分鐘 ``` ### 用戶ID 提取邏輯 (`AuthService.cs:25-54`) ```csharp Claims 查找優先順序: 1. ClaimTypes.NameIdentifier 2. "sub" claim 3. 嘗試解析為 Guid ``` --- ## 📋 配置管理分析 ### 環境變數配置 ```bash # JWT 相關 DRAMALING_SUPABASE_JWT_SECRET=<實際密鑰> DRAMALING_SUPABASE_URL= # API 服務 ASPNETCORE_ENVIRONMENT=Development|Production ``` ### 配置檔案 (`appsettings.json`) - **無敏感資訊洩露** ✅ - **所有密鑰為空字串** ✅ - **依賴環境變數或 User Secrets** ✅ --- ## 🎯 建議改進措施 ### 1. 立即修復(高優先級) #### 🔴 移除 FlashcardsController 的 AllowAnonymous ```csharp // 當前 [AllowAnonymous] public class FlashcardsController : BaseController // 建議改為 [Authorize] public class FlashcardsController : BaseController ``` #### 🔴 統一權限保護 為所有業務控制器添加 `[Authorize]` 屬性: - AIController - ImageGenerationController - OptionsVocabularyTestController ### 2. 安全性強化(中優先級) #### 🟡 硬編碼用戶ID 處理 ```csharp // 建議修改 BaseController.GetCurrentUserIdAsync() protected async Task GetCurrentUserIdAsync() { // ... JWT 解析邏輯 ... // 開發環境 fallback(僅限測試數據庫) if (IsTestEnvironment() && IsUsingTestDatabase()) { return Guid.Parse("00000000-0000-0000-0000-000000000001"); } throw new UnauthorizedAccessException("Invalid or missing user authentication"); } ``` #### 🟡 JWT Secret 強化 確保生產環境使用強密鑰: ```csharp // 添加密鑰強度檢查 if (environment != "Development" && jwtSecret.Length < 32) { throw new InvalidOperationException("Production JWT secret must be at least 32 characters"); } ``` ### 3. 監控和日誌(低優先級) #### 添加安全事件日誌 - 失敗的登入嘗試 - Token 驗證失敗 - 權限拒絕事件 #### 添加指標監控 - 活躍用戶數 - 認證失敗率 - API 調用頻率 --- ## 📊 總結 ### 優點 ✅ 完整的用戶註冊/登入流程 ✅ 安全的密碼雜湊(BCrypt) ✅ 標準的 JWT 認證機制 ✅ 配置安全(無硬編碼密鑰) ✅ 統一的錯誤處理 ### 待改進 🔴 部分控制器缺乏權限保護 🟡 開發環境硬編碼用戶ID 🟡 需要更完善的安全監控 ### 風險等級評估 **整體風險等級**: 🟡 **中等風險** 主要風險來自於 FlashcardsController 的 `[AllowAnonymous]` 設定,可能導致未認證用戶存取單字卡數據。建議優先修復此問題。 --- *分析完成時間: 2025-10-07* *後端服務狀態: 正常運行 (http://localhost:5000)*