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

30 lines
1.8 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
## Why
目前認證機制存在三個高危漏洞:Token 永不過期(一旦洩漏攻擊者永久持有存取權)、Google OAuth callback 將 Sanctum token 附在 URL query string(出現在 server log、瀏覽器歷史、Referer header),以及登入端點無頻率限制(暴力破解無防護)。三項缺陷均可在不入侵伺服器的前提下被利用。
## What Changes
- `config/sanctum.php`:將 `expiration``null` 改為 `10080`(7 天 × 24 小時 × 60 分鐘)
- `SocialAuthController::handleGoogleCallback()`redirect URL 改用 `#token=` fragment 取代 `?token=` query string
- `AuthCallbackView.vue`:改從 `window.location.hash` 讀取 token,不再使用 `route.query.token`
- `routes/api.php`:對 member / provider / admin 三個登入端點套用 `throttle:5,1` middleware
## Capabilities
### New Capabilities
- `login-rate-limiting`: 登入端點的請求頻率限制——每個 IP 每分鐘最多 5 次,超過回傳 429
### Modified Capabilities
- `provider-auth`: 新增登入 rate limiting 場景;新增 token 有效期行為(7 天後失效)
- `admin-auth`: 新增登入 rate limiting 場景;新增 token 有效期行為(7 天後失效)
- `member-portal-ui`: Google OAuth callback 行為變更——token 改由 URL fragment 傳遞,前端改從 hash 讀取
## Impact
- **後端**`config/sanctum.php``app/Http/Controllers/API/SocialAuthController.php``routes/api.php`
- **前端**`frontend/src/views/AuthCallbackView.vue`
- **現有 token**`expiration` 設定僅影響**新建立**的 token,既有的 `personal_access_tokens` 不受影響(`expires_at` 欄位為 null 的舊 token 仍長期有效),需另行清除或接受自然淘汰
- **無破壞性變更**API 介面、response 格式、前端路由均不改變