security(auth): P2 帳號鎖定 + OAuth state 驗證

- Account lockout:連續失敗 5 次鎖定 15 分鐘(Fixed Window,Cache)
  - Member / Provider 各自獨立 namespace
  - Email 正規化(strtolower+trim)
  - 不存在帳號不累計計數(防 Cache 污染)
  - companion key 記錄 locked_until(ISO 8601)
- OAuth CSRF 防護:移除 stateless(),手動 state 生成與驗證
  - session('oauth_state') + session('state') 雙寫確保 Socialite 內建驗證通過
  - state mismatch redirect 至 /login?error=oauth_failed
- throttle 從 5,1 調整為 10,1,避免 IP throttle 在 lockout 前觸發
- NormalizesEmail Trait、config/auth_lockout.php

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-06-03 01:20:25 +08:00
parent b2e20767d8
commit 2a0e9255ae
14 changed files with 680 additions and 47 deletions
+1 -1
View File
@@ -14,7 +14,7 @@ const error = ref('')
const loading = ref(false)
const oauthError = route.query.error === 'oauth_failed'
? 'Google 登入失敗,請重試'
? 'OAuth 授權失敗,請重新嘗試'
: ''
const successMsg = route.query.registered ? '註冊成功,請登入。' : ''