# Feature:會員系統(P0 介面;實作 TODO → Phase 1) > 父文件:[PRD.md](../PRD.md) | 對應 User Stories:US-01、US-02、US-13、US-22、US-TODO-01、US-TODO-02、US-TODO-03 > > **⚠️ 重要**:本功能**只在 Phase 0 定義介面**,**不實作真實 Auth**。 > Phase 0 的目標是讓雛形「看起來像有 Auth」:前端頁面有、後端 API 有、存個假的 session cookie,但 token 不驗簽、user 不落 DB。 > Phase 1 再換成真實 Auth(JWT / OAuth + DB)。 --- ## 範圍說明 | Phase 0 做 | Phase 1 做 | |-----------|-----------| | 登入頁 / 註冊頁 UI | 真實 Auth 後端 | | POST /api/auth/login / register 的 stub handler | JWT 簽發 / 驗證 | | 簡易 session cookie(in-memory) | Refresh token rotation | | 個人設定頁 UI 骨架 | 密碼重設流程 | | 登出功能(清 cookie) | Email 驗證 | | — | OAuth(Google / GitHub) | | — | 2FA | | — | 權限 / Role 系統 | --- ## 使用者行為(Phase 0) ### 登入頁(`/login`) - Email + 密碼輸入 - 「登入」按鈕 - 「還沒有帳號?註冊」連結 - (Phase 1):忘記密碼連結、OAuth 按鈕 ### 註冊頁(`/register`) - Email + 密碼 + 確認密碼 - 「建立帳號」按鈕 - Phase 0:submit 後直接登入(in-memory 記一個 user) - Phase 1:寄 email 驗證 + 存 DB ### 個人設定頁(`/account`) Phase 0:只做 UI 骨架,顯示 user email + 登出按鈕。 Phase 1 加: - 密碼變更 - Email 變更 - 頭像上傳 - 刪除帳號 - 2FA 設定 - 已連結的 OAuth 提供者 - API Key 管理 ### 登出 - 清除前端 token / cookie - 導回 `/login` --- ## 技術細節(給 Architect 參考) ### AuthProvider 介面 Phase 0 要定義清楚介面,Phase 1 直接換實作。 ```go // internal/auth/provider.go type AuthProvider interface { Register(ctx context.Context, email, password string) (*User, error) Login(ctx context.Context, email, password string) (*Session, error) ValidateToken(ctx context.Context, token string) (*User, error) Logout(ctx context.Context, token string) error // Phase 1: // RefreshToken(ctx context.Context, refreshToken string) (*Session, error) // RequestPasswordReset(ctx context.Context, email string) error // ConfirmPasswordReset(ctx context.Context, token, newPassword string) error } type User struct { ID string Email string // Phase 1:更多欄位(Name、Avatar、Created、...) } type Session struct { Token string UserID string ExpiresAt time.Time // Phase 1:RefreshToken string } ``` **Phase 0 實作:`StubAuthProvider`** - 記憶體 `map[string]*User`(email → user) - Session token = 隨機 32 字元(不簽、不驗) - 註冊與登入不做任何安全檢查(接受任何密碼) - 目的只是**讓前端能測整個流程**,不是真安全 **Phase 1 實作:`JWTAuthProvider`** - bcrypt 存密碼 - JWT 簽發(有 secret) - User 存 PostgreSQL - Refresh Token rotation - Rate limiting ### Auth Middleware api-server 的所有需要登入的 endpoint 都過 middleware: ```go func RequireAuth(provider AuthProvider) gin.HandlerFunc { return func(c *gin.Context) { token := extractToken(c) // from cookie or Authorization header user, err := provider.ValidateToken(c.Request.Context(), token) if err != nil { c.AbortWithStatusJSON(401, gin.H{"error": "unauthorized"}) return } c.Set("user", user) c.Next() } } ``` Phase 0 的 middleware 一樣跑,只是 `provider` 是 stub。 --- ## API 端點(Phase 0) | Method | Path | 說明 | |--------|------|------| | POST | `/api/auth/register` | 註冊(stub)| | POST | `/api/auth/login` | 登入(stub)| | POST | `/api/auth/logout` | 登出 | | GET | `/api/auth/me` | 取得當前 user 資訊 | Phase 1 加: | Method | Path | 說明 | |--------|------|------| | POST | `/api/auth/refresh` | Refresh token | | POST | `/api/auth/password/reset` | 請求密碼重設 | | POST | `/api/auth/password/confirm` | 確認密碼重設 | | POST | `/api/auth/oauth/{provider}` | OAuth callback | | DELETE | `/api/account` | 刪除帳號 | --- ## 驗收條件(Phase 0) - [ ] `/login`、`/register`、`/account` 三個頁面可打開 - [ ] 註冊 → 自動登入 → 跳轉到 `/` - [ ] 已登入狀態下訪問 `/login` → 自動跳 `/` - [ ] 未登入狀態下訪問需登入頁面(`/`、`/devices` 等)→ 跳 `/login` - [ ] 登出後 cookie 清除 - [ ] 兩個不同 user 的資料互相隔離(裝置列表、模型等) - [ ] AuthProvider 介面定義完整 - [ ] StubAuthProvider 實作能通過基本 flow - [ ] `/account` 頁面顯示當前 email + 登出按鈕(其他欄位灰掉或 TODO 標記) --- ## Phase 0 的 TODO 清單(明確追蹤) - **TODO-AUTH-01**:換 JWTAuthProvider(Phase 1 核心) - **TODO-AUTH-02**:DB 層(PostgreSQL schema for users、sessions) - **TODO-AUTH-03**:Email 驗證流程(需 email 服務,SendGrid / SES) - **TODO-AUTH-04**:密碼重設流程 - **TODO-AUTH-05**:OAuth(Google、GitHub) - **TODO-AUTH-06**:2FA(TOTP) - **TODO-AUTH-07**:密碼強度規則 - **TODO-AUTH-08**:Rate limiting(防暴力) - **TODO-AUTH-09**:Account 刪除(含所有裝置、模型、叢集清理) - **TODO-AUTH-10**:個人設定頁完整功能 - **TODO-AUTH-11**:Role / Permission 系統(Phase 2,for 企業版) - **TODO-AUTH-12**:API Key 管理(Phase 2) --- ## 安全警示(Phase 0 限制) ⚠️ **Phase 0 的 Auth 不是真的 Auth。絕對不能上線給真用戶。** 限制: - 密碼明文比對(in-memory) - Token 不簽、任何人偽造任何 token 都能通過 - 無 rate limiting - 無 HTTPS 強制(Phase 0 dev 環境可能 http://) **Phase 0 的 visionA Cloud 只給內部 FAE 測試**,不開放給外部。 --- ## 連結 - 回:[PRD 索引](../PRD.md) - 相關:[介面契約 — AuthProvider](../interface-contracts.md)