feat(callback): add callback

This commit is contained in:
2026-02-03 10:17:11 +08:00
parent 27a6791591
commit 202b5eaad5
27 changed files with 1806 additions and 124 deletions

211
LOCAL_E2E_RUNBOOK.md Normal file
View File

@@ -0,0 +1,211 @@
# 本地端到端联调iam-service + cms-service
目标:
- 生成临时 RSA 公私钥供 iam-service 使用RS256
- 启动 iam-service签发 token、发布 JWKS、提供权限裁决 `/authorize/check`
- 启动 cms-service本地验签 + 调用 IAM 做权限裁决)
- 在两个服务的 Scalar 页面完成:创建租户 → 注册用户 → 登录 → 调用 CMS 资源接口,验证“认证/权限由 IAM 控制”
> 本文不要求修改任何业务代码;只需要本地导出环境变量或创建 `.env` 文件。
## 0. 前置条件
- Rust支持 edition 2024与 Cargo
- PostgreSQL本机或 Docker并可使用 `psql`
- `openssl`
端口默认:
- iam-service3000
- cms-service3100
## 1. 准备数据库推荐Docker 一键起 PostgreSQL
启动 PostgreSQL
```bash
docker run --rm -d --name local-pg \
-e POSTGRES_PASSWORD=postgres \
-p 5432:5432 \
postgres:16
```
创建 iam/cms 两个数据库与用户(示例账号,可按需调整):
```bash
docker exec -i local-pg psql -U postgres <<'SQL'
CREATE USER iam_service_user WITH PASSWORD 'iam_service_password';
CREATE DATABASE iam_service_db OWNER iam_service_user;
GRANT ALL PRIVILEGES ON DATABASE iam_service_db TO iam_service_user;
CREATE USER cms_service_user WITH PASSWORD 'cms_service_password';
CREATE DATABASE cms_service_db OWNER cms_service_user;
GRANT ALL PRIVILEGES ON DATABASE cms_service_db TO cms_service_user;
SQL
```
准备连接串(后续会分别用于两服务):
- IAM`postgres://iam_service_user:iam_service_password@127.0.0.1:5432/iam_service_db`
- CMS`postgres://cms_service_user:cms_service_password@127.0.0.1:5432/cms_service_db`
## 2. 生成临时 RSA 公私钥RS256
```bash
KEY_DIR="$(mktemp -d)"
openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 -out "$KEY_DIR/jwt_private_key.pem"
openssl pkey -in "$KEY_DIR/jwt_private_key.pem" -pubout -out "$KEY_DIR/jwt_public_key.pem"
chmod 600 "$KEY_DIR/jwt_private_key.pem"
chmod 644 "$KEY_DIR/jwt_public_key.pem"
echo "KEY_DIR=$KEY_DIR"
```
说明:
- 私钥PKCS#8 PEM`BEGIN PRIVATE KEY`
- 公钥PKCS#8 公钥 PEM`BEGIN PUBLIC KEY`
- 该目录是临时目录,重启/清理后会消失;适合本地联调
## 3. 启动 iam-service签发 token + JWKS + 权限裁决)
在一个终端中执行(建议在 `iam-service` 目录下):
```bash
cd /home/shay/project/backend/iam-service
export PORT=3000
export DATABASE_URL='postgres://iam_service_user:iam_service_password@127.0.0.1:5432/iam_service_db'
# 用于 refresh token 指纹(不是 JWT 签名密钥),本地随便填一个即可
export JWT_SECRET='local-dev-refresh-token-pepper'
export JWT_KEY_ID='local-dev'
export JWT_PRIVATE_KEY_PEM="$(cat "$KEY_DIR/jwt_private_key.pem")"
export JWT_PUBLIC_KEY_PEM="$(cat "$KEY_DIR/jwt_public_key.pem")"
# 初始化/重建 DB会清库重建适合开发环境
BACKUP=0 ./scripts/db/rebuild_iam_db.sh
cargo run
```
启动后:
- IAM Scalar`http://127.0.0.1:3000/scalar`
- JWKS`http://127.0.0.1:3000/.well-known/jwks.json`
## 4. 启动 cms-service本地验签 + 调 IAM 裁权)
在另一个终端中执行(建议在 `cms-service` 目录下):
```bash
cd /home/shay/project/backend/cms-service
export PORT=3100
export DATABASE_URL='postgres://cms_service_user:cms_service_password@127.0.0.1:5432/cms_service_db'
export IAM_BASE_URL='http://127.0.0.1:3000'
# CMS 默认会走 IAM_BASE_URL + /.well-known/jwks.json 拉取公钥
# 如需显式指定:
# export IAM_JWKS_URL='http://127.0.0.1:3000/.well-known/jwks.json'
# 初始化/重建 DB会回滚并重建 cms schema适合开发环境
./scripts/db/rebuild_cms_db.sh
cargo run
```
启动后:
- CMS Scalar`http://127.0.0.1:3100/scalar`
## 5. 在 Scalar 中跑通“租户 → 注册 → 登录 → 调用 CMS 接口”
### 5.1 在 IAM Scalar 创建租户
打开 `http://127.0.0.1:3000/scalar`
1) 调用 `POST /tenants/register`
示例 body
```json
{ "name": "Tenant A" }
```
从响应中拿到 `tenant_id`UUID
### 5.2 在 IAM Scalar 注册首个用户(自动 Admin + CMS 权限)
调用 `POST /auth/register`
- Header`X-Tenant-ID: <tenant_id>`
- Body
```json
{ "email": "admin@example.com", "password": "Passw0rd!" }
```
重要说明:
- 该租户的**首个用户**会自动触发 bootstrap创建/获取 `Admin` 角色,并授予该租户下的全量非 `iam:*` 权限(包含 `cms:*` 权限),再绑定给该用户。
### 5.3 在 IAM Scalar 登录拿 token
调用 `POST /auth/login`
- Header`X-Tenant-ID: <tenant_id>`
- Body
```json
{ "email": "admin@example.com", "password": "Passw0rd!" }
```
保存响应中的:
- `access_token`
- `refresh_token`(可选,用于测试刷新)
### 5.4 在 CMS Scalar 调用资源接口(验证由 IAM 裁权)
打开 `http://127.0.0.1:3100/scalar`,选择任意需要权限的接口,例如:
- `POST /v1/columns`(需要 `cms:column:write`
在请求中设置:
- `Authorization: Bearer <access_token>`
- `X-Tenant-ID: <tenant_id>`
若一切正常:
- CMS 会先本地验签 tokenauth-kit
- 然后调用 IAM 的 `POST /authorize/check` 判断权限
- IAM 返回 allowed 后CMS 才会执行业务写入
验证建议:
- 观察 iam-service 控制台日志:应能看到 `/authorize/check` 的请求
- 如将 `access_token` 改成无效字符串CMS 会直接返回 401本地验签失败不会去请求 IAM
## 6. 常见问题(本地联调)
### 6.1 CMS 返回 401 MissingAuthHeader
- 检查是否在 CMS 请求里设置了 `Authorization: Bearer <access_token>`
- 检查 token 是否复制完整(不要带引号/空格)
### 6.2 CMS 返回 400 Missing X-Tenant-ID header
- CMS 需要 `X-Tenant-ID`
- 若同时提供 token + header但 tenant_id 不一致会返回 403tenant:mismatch
### 6.3 CMS 返回 403 PermissionDenied
- 表示 IAM 裁权拒绝(例如用户没有 `cms:*` 权限)
- 你可以在 IAM 中调用 `GET /me/permissions` 查看当前用户权限