template-monorepo/internal/model/auth/SDD.md

9.9 KiB
Raw Blame History

Auth Service

Auth Service — SRS/SDD Document

Version Version Date Editor Memo
1.0.0 2026/05/21 Gateway Team 初版Gateway Auth 模組 SDD

1. Introduction

1.1 Purpose

Auth 模組為 TianTing Gateway 的認證領域層提供租戶範圍內的原子化認證原語邀請碼、註冊稽核、OAuth 暫存 Session、CloudEP JWT 簽發/刷新/登出。完整 HTTP 流程由 internal/logic/auth/ 編排,並與 ZITADEL身份、Member會員、Notification通知協作。

1.2 Scope

範圍內:

  • 租戶邀請碼Validate / Consume
  • 註冊稽核 metadata條款版本、渠道、行銷 opt-in
  • OAuth 社交註冊/登入暫存 SessionRedis
  • CloudEP JWT access / refresh token 生命週期
  • JWT 黑名單與 jti pair 管理

範圍外(委派其他模組):

  • 使用者身份建立 → ZITADEL
  • 會員 profile、OTP → Member 模組
  • 郵件/簡訊 → Notification 模組
  • RBAC 授權 → Permission 模組 + Casbin middleware

1.3 Definitions, Acronyms, and Abbreviation

縮寫 說明
JWT JSON Web TokenCloudEP 自簽 access / refresh token
JTI JWT ID用於黑名單與 pair 映射
ROPG Resource Owner Password Grant密碼登入
OIDC OpenID Connect社交登入SSO
OTP One-Time Password由 Member 模組管理
Tenant 租戶,多租戶隔離單位
UID 租戶內可讀會員識別碼(如 ACME-10000003

1.4 Technologies to be used

項目 技術
Application Language Go 1.22+
Framework go-zero (rest, logx, stores/redis)
Cache / Session Redis
Database MongoDB
JWT github.com/golang-jwt/jwt/v4HS256
Identity Provider ZITADELinternal/library/zitadel
API Codegen goctl / .api

1.5 Overview

Auth 模組採 Clean Architecture 分層:domain/ 定義介面與實體,repository/ 實作 Mongo / Redis 適配器,usecase/ 提供原子 UseCase。HTTP handler 不直接存取 repository而是由 logic 層串接 ZITADEL + Member + Auth 原語。

主要流程:

  1. Email 註冊Consume invite → ZITADEL 建 user → Member 建 unverified → 發 OTP → confirm 後 Activate + IssuePair
  2. 密碼登入ZITADEL ROPG → 查 Member → IssuePair
  3. 社交註冊/登入Redis Session 暫存 OAuth state → callback 換 token → Provision / Login
  4. Token 刷新/登出Refresh 黑名單舊 pair 後重簽Logout 黑名單 access + refresh jti

2. System Overview

Auth 模組是 Gateway 認證子系統的核心,負責:

  • 控制誰可以註冊(邀請碼)
  • 記錄註冊合規稽核
  • 管理短期 OAuth 流程狀態
  • 簽發與驗證 CloudEP JWTmiddleware AuthJWT

對外透過 /api/v1/auth/* REST API 暴露JWT 驗證後將 (tenant_id, uid) 注入 request context供 Member / Permission 等下游使用。


3. System Architecture

3.1 System Architecture

flowchart TB
    subgraph Client["Client / Frontend"]
        Web[Web / Mobile App]
    end

    subgraph Gateway["Gateway"]
        Handler["handler/auth"]
        Logic["logic/auth<br/>(orchestration)"]
        subgraph AuthModule["internal/model/auth"]
            UC["usecase/"]
            Repo["repository/"]
            Domain["domain/"]
        end
        MW["middleware/AuthJWT"]
    end

    subgraph External["External Services"]
        Zitadel[ZITADEL IdP]
        Mongo[(MongoDB)]
        Redis[(Redis)]
    end

    subgraph Sibling["Sibling Modules"]
        Member[member]
        Notif[notification]
    end

    Web --> Handler
    Handler --> Logic
    Logic --> UC
    Logic --> Zitadel
    Logic --> Member
    Logic --> Notif
    UC --> Repo
    Repo --> Mongo
    Repo --> Redis
    MW --> UC

3.2 Decomposition Description

套件 職責
config/ JWT TTL、Session TTL 設定
domain/entity/ Mongo 文件模型InviteCode、RegistrationMetadata
domain/enum/ RegistrationChannelemail / google
domain/repository/ Port 介面 + Redis Session struct
domain/usecase/ UseCase 介面 + DTO
domain/const.go BSON 欄位名、Redis key、邀請碼 hash helper
domain/errors.go 領域 sentinel errors
repository/ Mongo + Redis 適配器、EnsureMongoIndexes
usecase/ 實作 + NewModuleFromParam factory
usecase/module.go 組裝 Invite / RegistrationMeta / Session UseCase

ServiceContext 注入:

欄位 UseCase 條件
AuthInvite InviteUseCase Mongo + Redis
AuthRegistrationMeta RegistrationMetaUseCase Mongo
AuthRegistrationSession RegistrationSessionUseCase Redis
AuthLoginSession LoginSessionUseCase Redis
AuthToken TokenUseCase JWT secret + Redis獨立於 Module

3.3 Token

CloudEP JWT 採 HS256access / refresh 使用不同 secret。

Claims 結構:

Claim 說明
tenant_id 租戶 ID
uid 會員 UID
typ accessrefresh
auth_gen 簽發世代(用於強制登出)
jti Token 唯一 ID
iat / exp 簽發/過期時間

預設 TTL

Token 預設
Access 900 秒15 分鐘)
Refresh 604800 秒7 天)
Registration Session 600 秒10 分鐘)

Redis 映射:

Key 用途
auth:jwt:pair:{jti} access ↔ refresh jti 雙向映射
auth:jwt:bl:{jti} 已登出/已刷新的 jti 黑名單

Refresh 流程:

sequenceDiagram
    participant C as Client
    participant L as TokenRefreshLogic
    participant T as TokenUseCase
    participant R as Redis

    C->>L: POST /auth/token/refresh {refresh_token}
    L->>T: Refresh(refreshToken)
    T->>T: Parse + verify typ=refresh
    T->>R: Blacklist old refresh jti + paired access jti
    T->>T: IssuePair(new access + refresh)
    T->>R: SavePair(new jti mapping)
    T-->>L: TokenPair
    L-->>C: AuthTokenData

3.4 Invite Code

邀請碼以 SHA-256 hash 儲存,明文永不落庫。

操作 行為
Validate (tenant_id, code_hash) 查詢,檢查過期與剩餘次數
Consume Redis SETNX lock30s→ 原子 $inc used_count

消費時機:

  • Email 註冊:在 /register 起始即 Consume
  • 社交註冊Start 僅 ValidateCallback 才 Consume

3.5 OAuth Session

Session 類型 Redis Key State 前綴 用途
Registration auth:register:session:{id} reg: 社交註冊暫存 invite / terms
Login auth:login:session:{id} login: 社交登入暫存 tenant / redirect

4. Data Design

4.1 Data Dictionary

invite_codesMongoDB

Field Type Comment Index
_id ObjectId PK PK
tenant_id String 租戶 ID Unique(tenant_id, code_hash)
code_hash String SHA-256(normalized code) Unique(tenant_id, code_hash)
max_uses Int64 最大可用次數
used_count Int64 已使用次數
expires_at Int64 過期時間 ms0=永不過期)
new_users_only Bool 僅限新用戶(社交註冊)
create_at Int64 建立時間 ms
update_at Int64 更新時間 ms

registration_metadataMongoDB

Field Type Comment Index
_id ObjectId PK PK
tenant_id String 租戶 ID Unique(tenant_id, uid)
uid String 會員 UID Unique(tenant_id, uid)
invite_code_id String 使用的邀請碼 ID
accept_terms_version String 接受的服務條款版本
marketing_opt_in Bool 行銷 opt-in
registration_channel String email / google
client_ip String 註冊 IP
user_agent String User-Agent
occurred_at Int64 事件時間 ms
create_at Int64 建立時間 ms

Redis Session / Token Keys

Key Pattern Type TTL Comment
auth:register:session:{id} String(JSON) 600s 社交註冊 OAuth session
auth:login:session:{id} String(JSON) 600s 社交登入 OAuth session
auth:invite:consume:{tenant}:{hash} String 30s 邀請碼消費鎖
auth:jwt:pair:{jti} String token TTL access↔refresh 映射
auth:jwt:bl:{jti} String 至自然過期 JWT 黑名單

5. API Design

Base Path /api/v1/auth

5.1 Public Endpoints無 Bearer

Method Path 說明
POST /register Email 註冊(回傳 challenge_id
POST /register/confirm OTP 確認 → 核發 JWT
POST /register/resend 重發註冊 OTP
POST /register/social/start 社交註冊 OAuth 起始
GET /register/social/callback 社交註冊 OAuth callback
POST /login 密碼登入
POST /login/social/start 社交登入 OAuth 起始
GET /login/social/callback 社交登入 OAuth callback
POST /token/refresh 刷新 token pair
POST /token/exchange ZITADEL id_token → CloudEP JWT

5.2 Protected Endpoints需 Bearer JWT

Method Path 說明
POST /logout 登出(黑名單 jti

完整請求/回應 schema 見 generate/api/auth.api;成功 envelope code=102000


6. Resource

資源 路徑
API 定義 generate/api/auth.api
Logic 編排 internal/logic/auth/
JWT Middleware internal/middleware/authjwt_*.go
模組原始碼 internal/model/auth/
設定範例 etc/gateway.dev.example.yamlAuth / JWT 區塊
設計參考 docs/identity-member-design.md