Files
member-platform/docs/BACKEND_ARCHITECTURE.md
2026-03-29 23:08:52 +08:00

94 lines
3.2 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.
# memberapi.ose.tw 後端架構FastAPI
## 1. 目標與邊界
- 網域:`memberapi.ose.tw`
- 角色會員中心後端真相來源User + Permission
- 範圍:
- user upsert`authentik_sub` 為跨系統主鍵)
- permission grant/revoke
- permission snapshot 提供給其他系統
- 不在本服務處理:
- Authentik OIDC 流程頁與 UI
- 前端互動邏輯
## 2. 技術棧
- Python 3.12
- FastAPI
- SQLAlchemy 2.0
- PostgreSQLpsycopg
- Pydantic Settings
## 3. 後端目錄(已建立)
- `backend/app/main.py`
- `backend/app/api/`
- `internal.py`
- `admin.py`
- `backend/app/core/config.py`
- `backend/app/db/session.py`
- `backend/app/models/`
- `user.py`
- `permission.py`
- `api_client.py`
- `backend/app/repositories/`
- `users_repo.py`
- `permissions_repo.py`
- `backend/app/security/api_client_auth.py`
- `backend/scripts/init_schema.sql`
- `backend/.env.example`
- `backend/.env.production.example`
## 4. 資料模型
- `users`
- `id`, `authentik_sub`(unique), `email`, `display_name`, `is_active`, timestamps
- `permissions`
- `id`, `user_id`, `scope_type`, `scope_id`, `module`, `action`, `created_at`
- unique constraint: `(user_id, scope_type, scope_id, module, action)`
- `api_clients`(由 `docs/API_CLIENTS_SQL.sql` 建立)
- `client_key`, `api_key_hash`, `status`, allowlist, expires/rate-limit 欄位
## 5. API 設計MVP
- 健康檢查
- `GET /healthz`
- 使用者路由Bearer token
- `GET /me`
- `GET /me/permissions/snapshot`
- Bearer token 由 Authentik JWT + JWKS 驗證,並以 `sub` 自動 upsert user
- 內部路由(系統對系統)
- `POST /internal/users/upsert-by-sub`
- `GET /internal/permissions/{authentik_sub}/snapshot`
- `POST /internal/authentik/users/ensure`
- header: `X-Internal-Secret`
- 管理路由(後台/API client
- `POST /admin/permissions/grant`
- `POST /admin/permissions/revoke`
- headers: `X-Client-Key`, `X-API-Key`
## 6. 安全策略
- `admin` 路由強制 API client 驗證:
- client 必須存在且 `status=active`
- `expires_at` 未過期
- `api_key_hash` 驗證(支援 `sha256:<hex>` 與 bcrypt/argon2
- allowlist 驗證origin/ip/path
- `internal` 路由使用 `X-Internal-Secret` 做服務間驗證
- `me` 路由使用 Authentik Access Token 驗證:
- 使用 `AUTHENTIK_JWKS_URL``AUTHENTIK_ISSUER` 推導 JWKS
- 可選 `AUTHENTIK_AUDIENCE` 驗證 aud claim
- Authentik Admin 整合:
- 使用 `AUTHENTIK_BASE_URL + AUTHENTIK_ADMIN_TOKEN`
- 可透過 `/internal/authentik/users/ensure` 建立或更新 Authentik user
- 建議上線前:
-`.env` 範本中的明文密碼改為部署平台 secret
- API key 全部改為 argon2/bcrypt hash
## 7. 與其他系統資料流
1. mkt/admin 後端登入後,以 token `sub` 呼叫 `/internal/users/upsert-by-sub`
2. 權限調整走 `/admin/permissions/grant|revoke`
3. 需要授權判斷時,呼叫 `/internal/permissions/{sub}/snapshot`
4. mkt 系統可本地快取 snapshot並做定時補償
## 8. 下一階段(建議)
- 加入 Alembic migration
- 為 permission/action 加 enum 與驗證規則
- 增加 audit log誰在何時授權/撤銷)
- 加入 rate-limit 與可觀測性metrics + request id