# 認證與授權 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 <refresh_token>
```

#### 回應範例
```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 <access_token>
```

#### 回應範例
```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 <refresh_token>"
```

### 安全測試
- **暴力破解測試**: 驗證帳號鎖定機制
- **Token洩漏測試**: 驗證Token黑名單機制
- **權限繞過測試**: 驗證角色權限控制
- **資料注入測試**: 驗證輸入清理機制

---

**模組負責人**: 後端團隊  
**最後更新**: 2024年9月7日  
**相關文檔**: [用戶管理API](./user-management.md), [錯誤處理](./errors.md)