# 認證與授權 API ## 📋 概述 Drama Ling 應用的認證與授權系統,支援傳統註冊登入和第三方社群登入(Apple ID、Google)。 ## 🔐 JWT 認證機制 ### Token 結構 ```json { "alg": "HS256", "typ": "JWT" } { "sub": "550e8400-e29b-41d4-a716-446655440000", "email": "user@example.com", "username": "dramatic_learner", "role": "user", // user, subscriber, admin "subscription_status": "active", // active, inactive, trial "iat": 1693920600, "exp": 1693924200 } ``` ### Token 生命週期 - **Access Token**: 1小時有效期 - **Refresh Token**: 30天有效期 - **Token 輪替**: 每次刷新會產生新的 Refresh Token - **Token 黑名單**: 登出時將 Token 加入黑名單 ## 📌 API 端點 ### 1. 用戶註冊 ```http POST /api/v1/auth/register Content-Type: application/json { "email": "user@example.com", "password": "securePassword123", "username": "dramatic_learner", "preferredLanguage": "en", "nativeLanguage": "zh-TW" } ``` #### 回應範例 ```http Response 201 Created { "success": true, "data": { "userId": "550e8400-e29b-41d4-a716-446655440000", "username": "dramatic_learner", "email": "user@example.com", "accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", "refreshToken": "550e8400-e29b-41d4-a716-446655440001", "expiresIn": 3600, "userRole": "user", "isNewUser": true }, "message": "User registered successfully", "meta": { "timestamp": "2024-09-07T12:00:00Z", "requestId": "550e8400-e29b-41d4-a716-446655440002" } } ``` #### 註冊驗證規則 - **Email**: 有效的電子郵件格式 - **Password**: 最少8位,包含大小寫字母和數字 - **Username**: 3-20字元,僅允許字母數字和底線 - **Language**: ISO 639-1 語言碼 #### 錯誤處理 ```http Response 400 Bad Request { "success": false, "error": { "code": "VALIDATION_ERROR", "message": "註冊資料驗證失敗", "details": { "email": ["Email format is invalid"], "password": ["Password must be at least 8 characters"], "username": ["Username already exists"] } } } ``` ### 2. 用戶登入 ```http POST /api/v1/auth/login Content-Type: application/json { "email": "user@example.com", "password": "securePassword123", "rememberMe": true } ``` #### 回應範例 ```http Response 200 OK { "success": true, "data": { "userId": "550e8400-e29b-41d4-a716-446655440000", "username": "dramatic_learner", "email": "user@example.com", "accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", "refreshToken": "550e8400-e29b-41d4-a716-446655440001", "expiresIn": 3600, "userRole": "subscriber", "subscriptionStatus": "active", "lastLoginAt": "2024-09-07T12:00:00Z" }, "message": "Login successful" } ``` #### 錯誤處理 ```http Response 401 Unauthorized { "success": false, "error": { "code": "INVALID_CREDENTIALS", "message": "Email或密碼錯誤", "details": { "attemptCount": 3, "lockoutTime": null } } } ``` ### 3. Token 刷新 ```http POST /api/v1/auth/refresh Authorization: Bearer ``` #### 回應範例 ```http Response 200 OK { "success": true, "data": { "accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", "refreshToken": "550e8400-e29b-41d4-a716-446655440001", "expiresIn": 3600, "tokenType": "Bearer" }, "message": "Token refreshed successfully" } ``` ### 4. 用戶登出 ```http POST /api/v1/auth/logout Authorization: Bearer ``` #### 回應範例 ```http Response 200 OK { "success": true, "data": { "loggedOut": true, "tokenBlacklisted": true }, "message": "Logout successful" } ``` ### 5. Apple ID 登入 ```http POST /api/v1/auth/apple Content-Type: application/json { "identityToken": "apple_identity_token", "authorizationCode": "apple_authorization_code", "userIdentifier": "apple_user_identifier", "email": "user@privaterelay.appleid.com", "fullName": { "givenName": "John", "familyName": "Doe" } } ``` #### 回應範例 ```http Response 200 OK { "success": true, "data": { "userId": "550e8400-e29b-41d4-a716-446655440000", "username": "apple_user_12345", "email": "user@privaterelay.appleid.com", "accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", "refreshToken": "550e8400-e29b-41d4-a716-446655440001", "expiresIn": 3600, "isNewUser": false, "authProvider": "apple" }, "message": "Apple login successful" } ``` ### 6. Google 登入 ```http POST /api/v1/auth/google Content-Type: application/json { "idToken": "google_id_token", "accessToken": "google_access_token", "serverAuthCode": "google_server_auth_code" } ``` #### 回應範例 ```http Response 200 OK { "success": true, "data": { "userId": "550e8400-e29b-41d4-a716-446655440000", "username": "google_user_12345", "email": "user@gmail.com", "accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", "refreshToken": "550e8400-e29b-41d4-a716-446655440001", "expiresIn": 3600, "isNewUser": true, "authProvider": "google" }, "message": "Google login successful" } ``` ## 🔒 權限控制 ### 用戶角色 ```typescript enum UserRole { USER = "user", // 免費用戶 SUBSCRIBER = "subscriber", // 訂閱用戶 ADMIN = "admin" // 管理員 } ``` ### 權限矩陣 | 功能 | 免費用戶 | 訂閱用戶 | 管理員 | |------|----------|----------|---------| | 基礎對話練習 | 3次/日 | 無限制 | 無限制 | | 高級對話功能 | ❌ | ✅ | ✅ | | 詞彙複習 | 基礎 | 進階 | 完整 | | 特殊任務 | 部分 | 完整 | 完整 | | 數據分析 | 基礎 | 詳細 | 完整 | | 管理功能 | ❌ | ❌ | ✅ | ### 權限檢查中介軟體 ```javascript // API 權限檢查範例 app.use('/api/v1/dialogues/advanced', requireSubscription); app.use('/api/v1/admin/*', requireAdminRole); function requireSubscription(req, res, next) { if (req.user.role !== 'subscriber' && req.user.role !== 'admin') { return res.status(403).json({ success: false, error: { code: "SUBSCRIPTION_REQUIRED", message: "此功能需要訂閱會員" } }); } next(); } ``` ## ⚡ 安全措施 ### 密碼安全 - **加密**: bcrypt + salt,成本因子 12 - **複雜度**: 最少8位,大小寫字母+數字 - **重設**: 臨時token,15分鐘有效期 ### 防攻擊機制 - **Rate Limiting**: 每IP每分鐘5次登入嘗試 - **帳號鎖定**: 5次失敗後鎖定15分鐘 - **CSRF Protection**: 所有POST請求需要CSRF token - **Input Sanitization**: 所有輸入進行清理和驗證 ### Token 安全 - **HTTPS Only**: 所有認證相關請求強制HTTPS - **HttpOnly Cookies**: Refresh token存放在HttpOnly cookie - **Token 黑名單**: 登出和可疑活動時加入黑名單 - **定期輪替**: 每24小時自動輪替長期token ## 🔧 錯誤碼 ### 認證相關錯誤 | 錯誤碼 | HTTP狀態 | 描述 | |--------|----------|------| | `INVALID_CREDENTIALS` | 401 | 登入憑證錯誤 | | `TOKEN_EXPIRED` | 401 | Token已過期 | | `TOKEN_INVALID` | 401 | Token無效或格式錯誤 | | `TOKEN_BLACKLISTED` | 401 | Token已被列入黑名單 | | `ACCOUNT_LOCKED` | 423 | 帳號因多次失敗嘗試被鎖定 | | `EMAIL_EXISTS` | 409 | 電子郵件已被註冊 | | `USERNAME_EXISTS` | 409 | 使用者名稱已存在 | | `VALIDATION_ERROR` | 400 | 輸入資料驗證失敗 | | `SOCIAL_LOGIN_ERROR` | 400 | 第三方登入驗證失敗 | ## 🧪 測試指南 ### 測試用例 ```bash # 正常註冊流程測試 curl -X POST https://api.dramaling.com/api/v1/auth/register \ -H "Content-Type: application/json" \ -d '{"email":"test@example.com","password":"Test123456","username":"testuser"}' # 登入流程測試 curl -X POST https://api.dramaling.com/api/v1/auth/login \ -H "Content-Type: application/json" \ -d '{"email":"test@example.com","password":"Test123456"}' # Token刷新測試 curl -X POST https://api.dramaling.com/api/v1/auth/refresh \ -H "Authorization: Bearer " ``` ### 安全測試 - **暴力破解測試**: 驗證帳號鎖定機制 - **Token洩漏測試**: 驗證Token黑名單機制 - **權限繞過測試**: 驗證角色權限控制 - **資料注入測試**: 驗證輸入清理機制 --- **模組負責人**: 後端團隊 **最後更新**: 2024年9月7日 **相關文檔**: [用戶管理API](./user-management.md), [錯誤處理](./errors.md)