Files
a620906209 cb9c9a9385 security(auth): P0 認證安全強化
- Token 過期時間設為 7 天(sanctum.php expiration)
- prune-expired 每日排程清除過期 token 記錄
- Google OAuth redirect 改用 URL fragment(#token=)避免 token 出現在 server log
- SocialAuthController env() 改 config() 修正 config:cache 下 redirect 失效問題
- 登入端點加 rate limiting:member/provider throttle:5,1,admin throttle:3,1
- axios/coachAxios 加 401 response interceptor,token 過期自動登出
- 修正 migration SQLite 相容性(MODIFY COLUMN),Feature tests 從 7 通過恢復至 41
- 新增 AuthRateLimitTest(5 tests)驗證各角色頻率限制行為

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-02 01:54:40 +08:00

2.5 KiB
Raw Permalink Blame History

1. Token 過期時間設定

  • 1.1 [後端] 修改 config/sanctum.php:將 'expiration' => null 改為 'expiration' => 60 * 24 * 710080 分鐘)
  • 1.2 [後端] 在 routes/console.php 新增排程:Schedule::command('sanctum:prune-expired --hours=168')->daily();,清除累積的過期 token 記錄
  • 1.3 [後端] 執行 php artisan config:clear 確認設定生效

2. Google OAuth Token 洩漏修復

  • 2.1 [後端] 修改 app/Http/Controllers/API/SocialAuthController.php 第 109、111 行:env('FRONTEND_URL') 改為 config('app.frontend_url')(防止 config:cache 後 env() 回傳 null),同時將第 109 行 ?token= 改為 #token=URL fragment
  • 2.2 [前端] 修改 frontend/src/views/AuthCallbackView.vue:將讀取 route.query.token 改為讀取 window.location.hashnew URLSearchParams(window.location.hash.substring(1)).get('token')

3. 登入端點 Rate Limiting

  • 3.1 [後端] 修改 routes/api.php:對 POST /api/member/login 套用 throttle:5,1 middleware
  • 3.2 [後端] 修改 routes/api.php:對 POST /api/provider/login 套用 throttle:5,1 middleware
  • 3.3 [後端] 修改 routes/api.php:對 POST /api/admin/login 套用 throttle:3,1 middleware(管理員帳號影響範圍更廣,採用更嚴格限制)
  • 3.4 [後端] 執行 php artisan route:clear 清除路由快取

4. 自動化測試

  • 4.1 [測試] 在 tests/Feature/AuthRateLimitTest.php 建立 Feature test:驗證 POST /api/member/login 第 6 次請求回傳 HTTP 429,並斷言 response header 含 Retry-After
  • 4.2 [測試] 在同一 test file 補充:POST /api/provider/login 第 6 次回傳 429POST /api/admin/login 第 4 次回傳 429admin 限制為 throttle:3,1
  • 4.3 [測試] 在 tests/Feature/AuthRateLimitTest.php 補充:正常登入(5 次以內)不受 throttle 影響,回傳 200 或 401

5. 手動驗證

  • 5.1 [整合測試] 驗證 Google OAuth 登入流程:登入後確認 Nginx access log 中 /auth/google/callback 的請求 URL 不含 token
  • 5.2 [整合測試] 驗證 Token 過期:在 personal_access_tokens 表手動將 expires_at 設為過去時間,確認 API 回傳 401 並自動登出
  • 5.3 [整合測試] 執行 php artisan sanctum:prune-expired --hours=168,確認 personal_access_tokens 中過期記錄被清除
  • 5.4 [整合測試] 驗證正常登入流程不受影響:member / provider 帳號各測試一次完整登入 → 操作 → 登出流程