dramaling-vocab-learning/backend-auth-analysis.md

6.0 KiB
Raw Permalink Blame History

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
  • 完整的輸入驗證

驗證規則:

Username: 3-50 字符長度
Email: 標準 Email 格式驗證
Password: 最少 8 字符

2. 登入系統 (AuthController.cs:112-175)

功能特點:

  • Email + 密碼認證
  • BCrypt 密碼驗證
  • JWT Token 生成
  • 統一錯誤訊息(避免用戶名洩露)

3. JWT Token 系統 (AuthController.cs:177-204)

設定分析:

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

    return Guid.Parse("00000000-0000-0000-0000-000000000001");
    
  2. ImageGenerationController.cs:160

    return Guid.Parse("00000000-0000-0000-0000-000000000001");
    

觸發條件

  • 開發環境 (ASPNETCORE_ENVIRONMENT=Development)
  • JWT Token 解析失敗時的 Fallback

風險評估

  • 開發環境: 可接受(便於測試)
  • 生產環境: 🔴 高風險(繞過認證)

🔧 AuthService 核心邏輯

Token 驗證流程 (AuthService.cs:56-101)

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)

Claims 查找優先順序:
1. ClaimTypes.NameIdentifier
2. "sub" claim
3. 嘗試解析為 Guid

📋 配置管理分析

環境變數配置

# JWT 相關
DRAMALING_SUPABASE_JWT_SECRET=<實際密鑰>
DRAMALING_SUPABASE_URL=<Supabase URL>

# API 服務
ASPNETCORE_ENVIRONMENT=Development|Production

配置檔案 (appsettings.json)

  • 無敏感資訊洩露
  • 所有密鑰為空字串
  • 依賴環境變數或 User Secrets

🎯 建議改進措施

1. 立即修復(高優先級)

🔴 移除 FlashcardsController 的 AllowAnonymous

// 當前
[AllowAnonymous]
public class FlashcardsController : BaseController

// 建議改為
[Authorize]
public class FlashcardsController : BaseController

🔴 統一權限保護

為所有業務控制器添加 [Authorize] 屬性:

  • AIController
  • ImageGenerationController
  • OptionsVocabularyTestController

2. 安全性強化(中優先級)

🟡 硬編碼用戶ID 處理

// 建議修改 BaseController.GetCurrentUserIdAsync()
protected async Task<Guid> GetCurrentUserIdAsync()
{
    // ... JWT 解析邏輯 ...

    // 開發環境 fallback僅限測試數據庫
    if (IsTestEnvironment() && IsUsingTestDatabase())
    {
        return Guid.Parse("00000000-0000-0000-0000-000000000001");
    }

    throw new UnauthorizedAccessException("Invalid or missing user authentication");
}

🟡 JWT Secret 強化

確保生產環境使用強密鑰:

// 添加密鑰強度檢查
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)