ZITADEL v2 不支援 password grant,改優先走 Sessions API 以恢復 Email 登入; dev-up 自動 seed 權限與 admin@k6.local,並改善使用者角色頁在無角色時仍可指派。 Co-authored-by: Cursor <cursoragent@cursor.com> |
||
|---|---|---|
| .. | ||
| README.md | ||
| gateway.dev.example.yaml | ||
| gateway.dev.yaml | ||
| gateway.k6.yaml | ||
| gateway.yaml | ||
| rbac.conf | ||
README.md
gateway.yaml 設定說明
Gateway 使用 go-zero conf 載入 YAML。結構定義在 internal/config/config.go,對應各模組的 Conf 結構。
用哪個檔案?
| 檔案 | 是否提交 git | 用途 |
|---|---|---|
gateway.yaml |
✅ | 預設:不需 Docker,僅 health |
gateway.dev.example.yaml |
✅ | 本機完整功能範例(無真實帳密) |
gateway.dev.yaml |
❌ 勿提交 | 你的本機設定(Port、DB、SMTP/SES/三竹帳密) |
# 第一次本機開發
cp etc/gateway.dev.example.yaml etc/gateway.dev.yaml
# 編輯 etc/gateway.dev.yaml(例如 Port、Mitake 帳密)— 此檔已在 .gitignore
make deps-up
make mongo-index
make run-dev # 會自動 setup-dev(缺檔時從 example 複製)
# 僅 API(不需 gateway.dev.yaml)
make run
go-zero 填寫規則(重要)
- 欄位名稱必須與 Go struct 一致(駝峰在 yaml 裡通常照抄,如
MaxPoolSize)。不要填 struct 裡沒有的欄位(例如以前的MaxStaleness),否則可能觸發奇怪錯誤。 - 沒標
optional的頂層欄位:在該區塊出現時需型別正確;我們已在 Mongo / Notification / Member 加上json:",optional",多數子欄位可省略。 - 空字串
"":可寫,表示無帳密 / 無 AuthSource。 - 時間:
30m、10s(time.Duration)。 - 字串陣列(如
Compressors)必須是 YAML 列表,不能寫成單一字串:Compressors: - zstd - snappy - Mongo 埠號:用整數
Port: 27017,不要Port: "27017";或直接在Host寫127.0.0.1:27017。
頂層:HTTP 服務(rest.RestConf)
| 欄位 | 必填 | 說明 | 範例 |
|---|---|---|---|
Name |
✓ | 服務名稱 | gateway |
Host |
✓ | 監聽位址 | 0.0.0.0 |
Port |
✓ | HTTP 埠 | 8888 |
其餘 RestConf 欄位(Timeout、Log、Prometheus 等)可省略,使用 go-zero 預設。
Mongo(internal/library/mongo.Conf)
Host 留空或整段註解 → 不連 Mongo,Notifier / MemberVerification 不會注入(仍可跑 health API)。
| 欄位 | 必填 | 說明 | 本機 dev 建議 |
|---|---|---|---|
Schema |
選 | 連線 scheme,預設 mongodb |
mongodb |
Host |
啟用時 ✓ | 主機;可含埠 127.0.0.1:27017 |
127.0.0.1 |
Port |
選 | Host 無埠時附加,整數 |
27017 |
Database |
啟用時 ✓ | 資料庫名 | gateway(與 docker init 一致) |
User |
選 | 帳號 | 本機留空 |
Password |
選 | 密碼 | 本機留空 |
AuthSource |
選 | 驗證用 DB;帳號在 admin 建則填 admin |
本機留空 |
ReplicaName |
選 | replica set 名稱 | 本機單機留空 |
TLS |
選 | 是否 tls=true |
false |
MaxPoolSize |
選 | 連線池上限 | 30 |
MinPoolSize |
選 | 連線池下限 | 10 |
MaxConnIdleTime |
選 | 閒置連線逾時 | 30m |
Compressors |
選 | 壓縮演算法陣列 | 省略(程式預設 zstd、snappy) |
ConnectTimeoutMs |
選 | 啟動 Ping 逾時(毫秒) | 省略(預設 10s) |
會建立的 collections(自動,無需手動建表):notifications、notification_dlq。索引:make mongo-index 或 docker init。
常見錯誤
| 錯誤訊息 | 原因 |
|---|---|
type mismatch for field "Mongo.Compressors" |
曾用不存在的 Port: "27017" 或 Compressors 寫成單一字串 |
field "Mongo.xxx" is not set |
舊版未加 optional;請更新程式或改用最精簡的 gateway.dev.yaml |
mongo: ping primary 失敗 |
有填 Mongo.Host 但沒跑 make deps-up |
Redis(go-zero redis.RedisConf)
Host 留空(gateway.yaml 預設)→ 不連 Redis。有 Mongo 時仍可用 memory 冪等/配額,但無異步重試 worker、無 Member OTP。
gateway.yaml 建議保留區塊並設空 Host:
Redis:
Host: ""
Type: node
| 欄位 | 必填 | 說明 | 本機 dev 建議 |
|---|---|---|---|
Host |
啟用時 ✓ | host:port |
localhost:6379 |
Type |
啟用時 ✓ | 單機填 node |
node |
Pass |
選 | 密碼 | 省略 |
Tls |
選 | TLS | 省略 |
Notification(internal/model/notification/config)
僅在 Mongo 已連線 時由 ServiceContext 組裝 Notifier。子欄位皆可省略(有程式預設)。
根層
| 欄位 | 說明 | 預設 / 建議 |
|---|---|---|
DefaultLocale |
模板語系 fallback | zh-tw |
RatePerTenant.Email |
每租戶每日 Email 上限 | 100 |
RatePerTenant.SMS |
每租戶每日 SMS 上限 | 50 |
Notification.Email
| 欄位 | 說明 |
|---|---|
Provider |
無真實 provider 時填 mock |
From |
寄件者(Send 時帶入) |
APIKey |
保留,目前未用 |
SMTP(Enable: true 時加入發信鏈,依 Sort failover):
| 欄位 | 說明 |
|---|---|
Enable / Sort |
是否啟用、優先順序(數字小先試) |
Host / Port |
SMTP 主機與埠(MailHog:localhost:1025) |
Username / Password |
認證 |
SES(AWS):
| 欄位 | 說明 |
|---|---|
Enable / Sort |
同上 |
Region / AccessKey / SecretKey / SessionToken |
AWS 憑證 |
Notification.SMS
| 欄位 | 說明 |
|---|---|
Provider |
無真實 provider 時 mock |
Mitake.Enable |
三竹簡訊 |
Mitake.User / Mitake.Password |
三竹帳密 |
Mitake.Sort |
failover 順序 |
Notification.Async
| 欄位 | 說明 |
|---|---|
QueueRedisKey |
Redis ZSET key(空則用內建 notif:retry:zset) |
Worker |
背景重試 goroutine 數 |
MaxRetry |
最大重試次數 |
BackoffSeconds |
重試間隔(秒)陣列 |
需 Mongo + Redis 才會啟動 RetryWorker。
Notification.Push / Webhook
保留欄位,目前未接線。
Member(internal/model/member/config)
僅在 Mongo + Redis + Notifier 皆就緒時注入 MemberVerification。
Member.OTP
| 欄位 | 說明 | 建議 |
|---|---|---|
Length |
OTP 位數 | 6 |
TTLSeconds |
challenge 存活秒數 | 300 |
MaxAttempts |
驗證嘗試上限 | 5 |
ResendCooldownSeconds |
重發冷卻 | 60 |
DailyVerifyLimit |
每日驗證上限 | 10 |
功能與依賴對照
flowchart LR
subgraph always [永遠可用]
H[health API]
end
subgraph mongo [Mongo.Host 有值]
N[Notifier Send/Get]
A[Admin DLQ]
end
subgraph redis [Redis.Host 有值]
Q[Enqueue + RetryWorker]
O[Member OTP]
end
H --> always
mongo --> N
mongo --> A
mongo --> redis
redis --> Q
redis --> O
| 你想用的功能 | Mongo | Redis |
|---|---|---|
/api/v1/health |
— | — |
Notifier.Send(同步) |
✓ | 選(冪等/配額建議開) |
Notifier.Enqueue + 重試 |
✓ | ✓ |
| Member 信箱/手機驗證 | ✓ | ✓ |
疑難排解
# 1. 只驗證 yaml 能否載入(不啟動服務)
go test ./internal/config/ -run TestLoadGatewayYAML -v
# 2. 看缺什麼欄位(啟動時)
go run gateway.go -f etc/gateway.yaml
# 3. dev 完整栈
make deps-up && make run-dev
# 4. 通知測試(單一入口,METHOD 指定測哪一種)
# 詳見 docs/notification-testing.md
make mongo-index
make notify-test METHOD=email-send TO=你的信箱@example.com
make notify-test METHOD=email-send TO=test@example.com MOCK=1
curl -s http://127.0.0.1:8888/api/v1/health
若你改壞了 yaml,可從 repo 內的 gateway.yaml / gateway.dev.yaml 重新複製,再依本文件逐段打開需要的區塊。
相關文件
- deploy/README.md — Docker Compose
- internal/model/notification/README.md — 通知模組
- internal/library/mongo/README.md — Mongo 存取層