94 lines
3.2 KiB
Markdown
94 lines
3.2 KiB
Markdown
# 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
|
||
- PostgreSQL(psycopg)
|
||
- 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)
|