visionA/docs/autoflow/02-prd/features/feature-auth.md
jim800121chen fb7da5d180 chore(autoflow): migrate .autoflow/ 共享層文件至 docs/autoflow/
依 autoflow-agent workspace v2 設計把 PRD / 設計 / 架構 / 交付類
共享文件從個人層 .autoflow/(ignored)搬到 docs/autoflow/(進 git),
讓團隊可共享產品與架構文件,個人層只留 progress / review / testing 等
per-branch 筆記。

- 02-prd/        21 個檔(PRD、features、market-analysis 等)
- 03-design/     18 個檔(design-spec、wireframes、flows 等)
- 04-architecture/ 31 個檔(TDD、design-doc、ADR×14、API 規格等)
- 07-delivery/   3 個檔(project-summary、phase-0.6-handover、stage-deployment-setup)

合計 73 檔。原檔已從 .autoflow/ 移除(migration 工具執行 git mv,
但因 .autoflow/ 在 .gitignore 中、git 將此操作視為新增、無 rename history)。
2026-05-04 16:55:55 +08:00

201 lines
5.9 KiB
Markdown
Raw 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.

# Feature會員系統P0 介面;實作 TODO → Phase 1
> 父文件:[PRD.md](../PRD.md) | 對應 User StoriesUS-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 再換成真實 AuthJWT / OAuth + DB
---
## 範圍說明
| Phase 0 做 | Phase 1 做 |
|-----------|-----------|
| 登入頁 / 註冊頁 UI | 真實 Auth 後端 |
| POST /api/auth/login / register 的 stub handler | JWT 簽發 / 驗證 |
| 簡易 session cookiein-memory | Refresh token rotation |
| 個人設定頁 UI 骨架 | 密碼重設流程 |
| 登出功能(清 cookie | Email 驗證 |
| — | OAuthGoogle / GitHub |
| — | 2FA |
| — | 權限 / Role 系統 |
---
## 使用者行為Phase 0
### 登入頁(`/login`
- Email + 密碼輸入
- 「登入」按鈕
- 「還沒有帳號?註冊」連結
- Phase 1忘記密碼連結、OAuth 按鈕
### 註冊頁(`/register`
- Email + 密碼 + 確認密碼
- 「建立帳號」按鈕
- Phase 0submit 後直接登入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 1RefreshToken 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**:換 JWTAuthProviderPhase 1 核心)
- **TODO-AUTH-02**DB 層PostgreSQL schema for users、sessions
- **TODO-AUTH-03**Email 驗證流程(需 email 服務SendGrid / SES
- **TODO-AUTH-04**:密碼重設流程
- **TODO-AUTH-05**OAuthGoogle、GitHub
- **TODO-AUTH-06**2FATOTP
- **TODO-AUTH-07**:密碼強度規則
- **TODO-AUTH-08**Rate limiting防暴力
- **TODO-AUTH-09**Account 刪除(含所有裝置、模型、叢集清理)
- **TODO-AUTH-10**:個人設定頁完整功能
- **TODO-AUTH-11**Role / Permission 系統Phase 2for 企業版)
- **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)